193 $basename =
'getListProcs';
195 $sep =
' & "' . self::STR_SEPARATOR .
'" & _';
197 $content =
'Dim objFso, objResultFile, objWMIService' . PHP_EOL . PHP_EOL;
198 $content .=
'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL;
199 $content .=
'Set objResultFile = objFso.CreateTextFile("' . $resultFile .
'", True)' . PHP_EOL;
200 $content .=
'strComputer = "."' . PHP_EOL;
201 $content .=
'Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\\\" & strComputer & "\root\cimv2")' . PHP_EOL;
202 $content .=
'Set listProcess = objWMIService.ExecQuery ("SELECT * FROM Win32_Process")' . PHP_EOL;
203 $content .=
'For Each process in listProcess' . PHP_EOL;
205 $content .=
' objResultFile.WriteLine(_' . PHP_EOL;
206 foreach ( $vbsKeys as $vbsKey ) {
207 $content .=
' process.' . $vbsKey . $sep . PHP_EOL;
209 $content = substr( $content, 0, strlen( $content ) - strlen( $sep ) - 1 ) .
')' . PHP_EOL;
211 $content .=
'Next' . PHP_EOL;
212 $content .=
'objResultFile.WriteLine("' . self::END_PROCESS_STR .
'")' . PHP_EOL;
213 $content .=
'objResultFile.Close' . PHP_EOL;
214 $content .=
'Err.Clear' . PHP_EOL;
223 $rebuildResult = array();
225 $row = explode( trim( self::STR_SEPARATOR ), $row );
226 if ( count( $row ) != count( $vbsKeys ) ) {
229 $processInfo = array();
230 foreach ( $vbsKeys as $key => $vbsKey ) {
231 $processInfo[$vbsKey] = trim( $row[$key] );
234 $rebuildResult[] = $processInfo;
238 return $rebuildResult;
466 public static function exec($basename, $resultFile, $content, $timeout = true)
468 global $bearsamppConfig, $bearsamppWinbinder;
471 $scriptPath = self::getTmpFile( '.vbs', $basename );
472 $checkFile = self::getTmpFile( '.tmp', $basename );
473 $errFile = self::getTmpFile( '.tmp', $basename );
474 $randomVarName = Util::random( 15, false );
475 $randomObjErrFile = Util::random( 15, false );
476 $randomObjFile = Util::random( 15, false );
477 $randomObjFso = Util::random( 15, false );
479 // Add a timeout to the VBScript itself
480 $timeoutSeconds = 10; // 10 seconds timeout for the VBScript
482 // Header with timeout
483 $header = 'On Error Resume Next' . PHP_EOL .
484 'Dim ' . $randomVarName . ', ' . $randomObjFso . ', ' . $randomObjErrFile . ', ' . $randomObjFile . PHP_EOL .
485 'Set ' . $randomObjFso . ' = CreateObject("scripting.filesystemobject
")' . PHP_EOL .
486 'Set ' . $randomObjErrFile . ' = ' . $randomObjFso . '.CreateTextFile("' . $errFile . '", True)' . PHP_EOL .
487 'Set ' . $randomObjFile . ' = ' . $randomObjFso . '.CreateTextFile("' . $checkFile . '", True)' . PHP_EOL .
488 // Add timeout mechanism to VBScript
489 'startTime = Timer' . PHP_EOL .
490 'timeoutSeconds = ' . $timeoutSeconds . PHP_EOL . PHP_EOL;
492 // Footer with timeout check
493 $footer = PHP_EOL . PHP_EOL .
494 // Add timeout check before ending
495 'If Timer - startTime > timeoutSeconds Then' . PHP_EOL .
496 $randomObjErrFile . '.Write "VBScript execution timed out after
" & timeoutSeconds & " seconds
"' . PHP_EOL .
498 'If Err.Number <> 0 Then' . PHP_EOL .
499 $randomObjErrFile . '.Write Err.Description' . PHP_EOL .
501 $randomObjFile . '.Write "' . self::END_PROCESS_STR . '"' . PHP_EOL .
502 $randomObjFile . '.Close' . PHP_EOL .
503 $randomObjErrFile . '.Close' . PHP_EOL;
506 file_put_contents( $scriptPath, $header . $content . $footer );
508 // Use set_time_limit to prevent PHP script timeout
509 $originalTimeout = ini_get('max_execution_time');
510 set_time_limit(30); // 30 seconds timeout for PHP
512 Util::logTrace("Starting VBS execution
for:
" . $basename);
513 $startTime = microtime(true);
516 $bearsamppWinbinder->exec( 'wscript.exe', '"' . $scriptPath . '"' );
518 $timeout = is_numeric( $timeout ) ? $timeout : ($timeout === true ? $bearsamppConfig->getScriptsTimeout() : false);
519 // Use a shorter timeout for VBS execution
520 $timeout = min($timeout, 15); // Maximum 15 seconds
521 $maxtime = time() + $timeout;
522 $noTimeout = $timeout === false;
524 // Add a microtime-based timeout as well
525 $microTimeStart = microtime(true);
526 $microTimeMax = 15; // 15 seconds maximum
529 $maxLoops = 30; // Maximum number of attempts
531 while ( ($result === false || empty( $result )) && $loopCount < $maxLoops ) {
534 if ( file_exists( $checkFile ) ) {
535 $check = file( $checkFile );
536 if ( !empty( $check ) && trim( $check[0] ) == self::END_PROCESS_STR ) {
537 $result = file( $resultFile );
538 Util::logTrace("VBS execution completed successfully after
" . $loopCount . " attempts
");
543 // Check both timeouts
544 if (($maxtime < time() && !$noTimeout) || (microtime(true) - $microTimeStart > $microTimeMax)) {
545 Util::logTrace("VBS execution timed out after
" . round(microtime(true) - $startTime, 2) . " seconds
");
549 // Sleep a short time to prevent CPU hogging
550 usleep(100000); // 100ms
553 if ($loopCount >= $maxLoops) {
554 Util::logTrace("VBS execution reached maximum loop count (
" . $maxLoops . ")
");
556 } catch (\Exception $e) {
557 Util::logTrace("Exception during VBS execution:
" . $e->getMessage());
558 } catch (\Throwable $e) {
559 Util::logTrace("Throwable during VBS execution:
" . $e->getMessage());
562 set_time_limit($originalTimeout);
565 $executionTime = round(microtime(true) - $startTime, 2);
566 Util::logTrace("VBS execution
for " . $basename . " took
" . $executionTime . " seconds
");
568 $err = file_get_contents( $errFile );
569 if ( !empty( $err ) ) {
570 Util::logError( 'VBS error on ' . $basename . ': ' . $err );
573 self::writeLog( 'Exec ' . $basename . ':' );
574 self::writeLog( '-> content: ' . str_replace( PHP_EOL, ' \\\\ ', $content ) );
575 self::writeLog( '-> errFile: ' . $errFile );
576 self::writeLog( '-> checkFile: ' . $checkFile );
577 self::writeLog( '-> resultFile: ' . $resultFile );
578 self::writeLog( '-> scriptPath: ' . $scriptPath );
580 if ( $result !== false && !empty( $result ) ) {
581 $rebuildResult = array();
582 foreach ( $result as $row ) {
584 if ( !empty( $row ) ) {
585 $rebuildResult[] = $row;
588 $result = $rebuildResult;
589 self::writeLog( '-> result: ' . substr( implode( ' \\\\ ', $result ), 0, 2048 ) );
592 self::writeLog( '-> result: N/A' );