//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// // WaitAndRestart.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "tier1/strtools.h" #include "vmpi_defs.h" void PrintLog( const char *pMsg, ... ) { #ifdef VMPI_SERVICE_LOGS char str[4096]; va_list marker; va_start( marker, pMsg ); _vsnprintf( str, sizeof( str ), pMsg, marker ); va_end( marker ); printf( "%s", str ); static FILE *fp = fopen( "c:\\vmpi_WaitAndRestart.log", "wt" ); if ( fp ) { fprintf( fp, "%s", str ); fflush( fp ); } #endif } char* GetLastErrorString() { static char err[2048]; LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); strncpy( err, (char*)lpMsgBuf, sizeof( err ) ); LocalFree( lpMsgBuf ); err[ sizeof( err ) - 1 ] = 0; return err; } int main( int argc, char* argv[] ) { Sleep(5000); if ( argc < 4 ) { PrintLog( "WaitAndRestart command line...\n" ); return 1; } PrintLog( "WaitAndRestart command line...\n" ); const char *pTimeToWait = argv[1]; const char *pWorkingDir = argv[2]; // If a * precedes the time-to-wait arg, then it's a process ID and we wait for that process to exit. if ( pTimeToWait[0] == '*' ) { ++pTimeToWait; DWORD dwProcessId; sscanf( pTimeToWait, "%lu", &dwProcessId ); PrintLog( "Waiting for process %lu to exit. Press a key to cancel...\n", dwProcessId ); HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | SYNCHRONIZE, false, dwProcessId ); if ( hProcess ) { while ( 1 ) { DWORD val = WaitForSingleObject( hProcess, 100 ); if ( val == WAIT_OBJECT_0 ) { break; } else if ( val == WAIT_ABANDONED ) { PrintLog( "Got WAIT_ABANDONED (error). Waiting 5 seconds, then continuing.\n" ); Sleep( 5000 ); break; } if ( kbhit() ) return 2; } PrintLog( "Process %lu terminated. Continuing.\n", dwProcessId ); } else { PrintLog( "Process %lu not running. Continuing.\n", dwProcessId ); } CloseHandle( hProcess ); } else { DWORD timeToWait = (DWORD)atoi( argv[1] ); PrintLog( "\n\nWaiting for %d seconds to launch ' ", timeToWait ); PrintLog( "%s> ", pWorkingDir ); for ( int i=3; i < argc; i++ ) { PrintLog( "%s ", argv[i] ); } PrintLog( "'\n\nPress a key to cancel... " ); DWORD startTime = GetTickCount(); while ( GetTickCount() - startTime < (timeToWait*1000) ) { if ( kbhit() ) return 2; Sleep( 100 ); } } // Ok, launch it! char commandLine[1024] = {0}; for ( int i=3; i < argc; i++ ) { Q_strncat( commandLine, "\"", sizeof( commandLine ), COPY_ALL_CHARACTERS ); Q_strncat( commandLine, argv[i], sizeof( commandLine ), COPY_ALL_CHARACTERS ); Q_strncat( commandLine, "\" ", sizeof( commandLine ), COPY_ALL_CHARACTERS ); } STARTUPINFO si; memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); PROCESS_INFORMATION pi; memset( &pi, 0, sizeof( pi ) ); if ( CreateProcess( NULL, commandLine, NULL, // security NULL, FALSE, 0, // flags NULL, // environment pWorkingDir, // current directory &si, &pi ) ) { PrintLog( "Process started.\n" ); CloseHandle( pi.hThread ); // We don't care what the process does. CloseHandle( pi.hProcess ); } else { PrintLog( "CreateProcess error!\n%s", GetLastErrorString() ); } return 0; }