166 $basename =
'getListProcs';
168 $sep =
' & "' . self::STR_SEPARATOR .
'" & _';
170 $content =
'Dim objFso, objResultFile, objWMIService' . PHP_EOL . PHP_EOL;
171 $content .=
'Set objFso = CreateObject("scripting.filesystemobject")' . PHP_EOL;
172 $content .=
'Set objResultFile = objFso.CreateTextFile("' . $resultFile .
'", True)' . PHP_EOL;
173 $content .=
'strComputer = "."' . PHP_EOL;
174 $content .=
'Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\\\" & strComputer & "\root\cimv2")' . PHP_EOL;
175 $content .=
'Set listProcess = objWMIService.ExecQuery ("SELECT * FROM Win32_Process")' . PHP_EOL;
176 $content .=
'For Each process in listProcess' . PHP_EOL;
178 $content .=
' objResultFile.WriteLine(_' . PHP_EOL;
179 foreach ( $vbsKeys as $vbsKey ) {
180 $content .=
' process.' . $vbsKey . $sep . PHP_EOL;
182 $content = substr( $content, 0, strlen( $content ) - strlen( $sep ) - 1 ) .
')' . PHP_EOL;
184 $content .=
'Next' . PHP_EOL;
185 $content .=
'objResultFile.WriteLine("' . self::END_PROCESS_STR .
'")' . PHP_EOL;
186 $content .=
'objResultFile.Close' . PHP_EOL;
187 $content .=
'Err.Clear' . PHP_EOL;
196 $rebuildResult = array();
198 $row = explode( trim( self::STR_SEPARATOR ), $row );
199 if ( count( $row ) != count( $vbsKeys ) ) {
202 $processInfo = array();
203 foreach ( $vbsKeys as $key => $vbsKey ) {
204 $processInfo[$vbsKey] = trim( $row[$key] );
207 $rebuildResult[] = $processInfo;
211 return $rebuildResult;
439 public static function exec($basename, $resultFile, $content, $timeout = true)
441 global $bearsamppConfig, $bearsamppWinbinder;
444 $scriptPath = self::getTmpFile( '.vbs', $basename );
445 $checkFile = self::getTmpFile( '.tmp', $basename );
446 $errFile = self::getTmpFile( '.tmp', $basename );
447 $randomVarName = Util::random( 15, false );
448 $randomObjErrFile = Util::random( 15, false );
449 $randomObjFile = Util::random( 15, false );
450 $randomObjFso = Util::random( 15, false );
452 // Add a timeout to the VBScript itself
453 $timeoutSeconds = 10; // 10 seconds timeout for the VBScript
455 // Header with timeout
456 $header = 'On Error Resume Next' . PHP_EOL .
457 'Dim ' . $randomVarName . ', ' . $randomObjFso . ', ' . $randomObjErrFile . ', ' . $randomObjFile . PHP_EOL .
458 'Set ' . $randomObjFso . ' = CreateObject("scripting.filesystemobject
")' . PHP_EOL .
459 'Set ' . $randomObjErrFile . ' = ' . $randomObjFso . '.CreateTextFile("' . $errFile . '", True)' . PHP_EOL .
460 'Set ' . $randomObjFile . ' = ' . $randomObjFso . '.CreateTextFile("' . $checkFile . '", True)' . PHP_EOL .
461 // Add timeout mechanism to VBScript
462 'startTime = Timer' . PHP_EOL .
463 'timeoutSeconds = ' . $timeoutSeconds . PHP_EOL . PHP_EOL;
465 // Footer with timeout check
466 $footer = PHP_EOL . PHP_EOL .
467 // Add timeout check before ending
468 'If Timer - startTime > timeoutSeconds Then' . PHP_EOL .
469 $randomObjErrFile . '.Write "VBScript execution timed out after
" & timeoutSeconds & " seconds
"' . PHP_EOL .
471 'If Err.Number <> 0 Then' . PHP_EOL .
472 $randomObjErrFile . '.Write Err.Description' . PHP_EOL .
474 $randomObjFile . '.Write "' . self::END_PROCESS_STR . '"' . PHP_EOL .
475 $randomObjFile . '.Close' . PHP_EOL .
476 $randomObjErrFile . '.Close' . PHP_EOL;
479 file_put_contents( $scriptPath, $header . $content . $footer );
481 // Use set_time_limit to prevent PHP script timeout
482 $originalTimeout = ini_get('max_execution_time');
483 set_time_limit(30); // 30 seconds timeout for PHP
485 Util::logTrace("Starting VBS execution
for:
" . $basename);
486 $startTime = microtime(true);
489 $bearsamppWinbinder->exec( 'wscript.exe', '"' . $scriptPath . '"' );
491 $timeout = is_numeric( $timeout ) ? $timeout : ($timeout === true ? $bearsamppConfig->getScriptsTimeout() : false);
492 // Use a shorter timeout for VBS execution
493 $timeout = min($timeout, 15); // Maximum 15 seconds
494 $maxtime = time() + $timeout;
495 $noTimeout = $timeout === false;
497 // Add a microtime-based timeout as well
498 $microTimeStart = microtime(true);
499 $microTimeMax = 15; // 15 seconds maximum
502 $maxLoops = 30; // Maximum number of attempts
504 while ( ($result === false || empty( $result )) && $loopCount < $maxLoops ) {
507 if ( file_exists( $checkFile ) ) {
508 $check = file( $checkFile );
509 if ( !empty( $check ) && trim( $check[0] ) == self::END_PROCESS_STR ) {
510 $result = file( $resultFile );
511 Util::logTrace("VBS execution completed successfully after
" . $loopCount . " attempts
");
516 // Check both timeouts
517 if (($maxtime < time() && !$noTimeout) || (microtime(true) - $microTimeStart > $microTimeMax)) {
518 Util::logTrace("VBS execution timed out after
" . round(microtime(true) - $startTime, 2) . " seconds
");
522 // Sleep a short time to prevent CPU hogging
523 usleep(100000); // 100ms
526 if ($loopCount >= $maxLoops) {
527 Util::logTrace("VBS execution reached maximum loop count (
" . $maxLoops . ")
");
529 } catch (\Exception $e) {
530 Util::logTrace("Exception during VBS execution:
" . $e->getMessage());
531 } catch (\Throwable $e) {
532 Util::logTrace("Throwable during VBS execution:
" . $e->getMessage());
535 set_time_limit($originalTimeout);
538 $executionTime = round(microtime(true) - $startTime, 2);
539 Util::logTrace("VBS execution
for " . $basename . " took
" . $executionTime . " seconds
");
541 $err = file_get_contents( $errFile );
542 if ( !empty( $err ) ) {
543 Util::logError( 'VBS error on ' . $basename . ': ' . $err );
546 self::writeLog( 'Exec ' . $basename . ':' );
547 self::writeLog( '-> content: ' . str_replace( PHP_EOL, ' \\\\ ', $content ) );
548 self::writeLog( '-> errFile: ' . $errFile );
549 self::writeLog( '-> checkFile: ' . $checkFile );
550 self::writeLog( '-> resultFile: ' . $resultFile );
551 self::writeLog( '-> scriptPath: ' . $scriptPath );
553 if ( $result !== false && !empty( $result ) ) {
554 $rebuildResult = array();
555 foreach ( $result as $row ) {
557 if ( !empty( $row ) ) {
558 $rebuildResult[] = $row;
561 $result = $rebuildResult;
562 self::writeLog( '-> result: ' . substr( implode( ' \\\\ ', $result ), 0, 2048 ) );
565 self::writeLog( '-> result: N/A' );