Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
3.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // WaitAndRestart.cpp : Defines the entry point for the console application.
  9. //
  10. #include "stdafx.h"
  11. #include "tier1/strtools.h"
  12. #include "vmpi_defs.h"
  13. void PrintLog( const char *pMsg, ... )
  14. {
  15. #ifdef VMPI_SERVICE_LOGS
  16. char str[4096];
  17. va_list marker;
  18. va_start( marker, pMsg );
  19. _vsnprintf( str, sizeof( str ), pMsg, marker );
  20. va_end( marker );
  21. printf( "%s", str );
  22. static FILE *fp = fopen( "c:\\vmpi_WaitAndRestart.log", "wt" );
  23. if ( fp )
  24. {
  25. fprintf( fp, "%s", str );
  26. fflush( fp );
  27. }
  28. #endif
  29. }
  30. char* GetLastErrorString()
  31. {
  32. static char err[2048];
  33. LPVOID lpMsgBuf;
  34. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
  35. strncpy( err, (char*)lpMsgBuf, sizeof( err ) );
  36. LocalFree( lpMsgBuf );
  37. err[ sizeof( err ) - 1 ] = 0;
  38. return err;
  39. }
  40. int main( int argc, char* argv[] )
  41. {
  42. Sleep(5000);
  43. if ( argc < 4 )
  44. {
  45. PrintLog( "WaitAndRestart <seconds to wait> <working directory> command line...\n" );
  46. return 1;
  47. }
  48. PrintLog( "WaitAndRestart <seconds to wait> <working directory> command line...\n" );
  49. const char *pTimeToWait = argv[1];
  50. const char *pWorkingDir = argv[2];
  51. // If a * precedes the time-to-wait arg, then it's a process ID and we wait for that process to exit.
  52. if ( pTimeToWait[0] == '*' )
  53. {
  54. ++pTimeToWait;
  55. DWORD dwProcessId;
  56. sscanf( pTimeToWait, "%lu", &dwProcessId );
  57. PrintLog( "Waiting for process %lu to exit. Press a key to cancel...\n", dwProcessId );
  58. HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | SYNCHRONIZE, false, dwProcessId );
  59. if ( hProcess )
  60. {
  61. while ( 1 )
  62. {
  63. DWORD val = WaitForSingleObject( hProcess, 100 );
  64. if ( val == WAIT_OBJECT_0 )
  65. {
  66. break;
  67. }
  68. else if ( val == WAIT_ABANDONED )
  69. {
  70. PrintLog( "Got WAIT_ABANDONED (error). Waiting 5 seconds, then continuing.\n" );
  71. Sleep( 5000 );
  72. break;
  73. }
  74. if ( kbhit() )
  75. return 2;
  76. }
  77. PrintLog( "Process %lu terminated. Continuing.\n", dwProcessId );
  78. }
  79. else
  80. {
  81. PrintLog( "Process %lu not running. Continuing.\n", dwProcessId );
  82. }
  83. CloseHandle( hProcess );
  84. }
  85. else
  86. {
  87. DWORD timeToWait = (DWORD)atoi( argv[1] );
  88. PrintLog( "\n\nWaiting for %d seconds to launch ' ", timeToWait );
  89. PrintLog( "%s> ", pWorkingDir );
  90. for ( int i=3; i < argc; i++ )
  91. {
  92. PrintLog( "%s ", argv[i] );
  93. }
  94. PrintLog( "'\n\nPress a key to cancel... " );
  95. DWORD startTime = GetTickCount();
  96. while ( GetTickCount() - startTime < (timeToWait*1000) )
  97. {
  98. if ( kbhit() )
  99. return 2;
  100. Sleep( 100 );
  101. }
  102. }
  103. // Ok, launch it!
  104. char commandLine[1024] = {0};
  105. for ( int i=3; i < argc; i++ )
  106. {
  107. Q_strncat( commandLine, "\"", sizeof( commandLine ), COPY_ALL_CHARACTERS );
  108. Q_strncat( commandLine, argv[i], sizeof( commandLine ), COPY_ALL_CHARACTERS );
  109. Q_strncat( commandLine, "\" ", sizeof( commandLine ), COPY_ALL_CHARACTERS );
  110. }
  111. STARTUPINFO si;
  112. memset( &si, 0, sizeof( si ) );
  113. si.cb = sizeof( si );
  114. PROCESS_INFORMATION pi;
  115. memset( &pi, 0, sizeof( pi ) );
  116. if ( CreateProcess(
  117. NULL,
  118. commandLine,
  119. NULL, // security
  120. NULL,
  121. FALSE,
  122. 0, // flags
  123. NULL, // environment
  124. pWorkingDir, // current directory
  125. &si,
  126. &pi ) )
  127. {
  128. PrintLog( "Process started.\n" );
  129. CloseHandle( pi.hThread ); // We don't care what the process does.
  130. CloseHandle( pi.hProcess );
  131. }
  132. else
  133. {
  134. PrintLog( "CreateProcess error!\n%s", GetLastErrorString() );
  135. }
  136. return 0;
  137. }