fork download
  1. #include <iostream>
  2. #include <Windows.h>
  3. #include <ShellAPI.h>
  4. #include <io.h>
  5. #include <stdlib.h>
  6. #include <sstream>
  7. #include <vector>
  8. #include <string>
  9.  
  10. #pragma comment(lib, "shell32.lib")
  11.  
  12. void system_error(wchar_t *name) {
  13. // Retrieve, format, and print out a message from the last error.
  14. // The `name' that's passed should be in the form of a present tense
  15. // noun (phrase) such as "opening file".
  16. //
  17. wchar_t *ptr = NULL;
  18. FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  19. FORMAT_MESSAGE_FROM_SYSTEM,
  20. 0, GetLastError(), 0, (wchar_t *)&ptr, 1024, NULL);
  21.  
  22. LocalFree(ptr);
  23. }
  24.  
  25. std::wstring find_image(std::wstring const &name) {
  26. // Try to find an image file named by the user.
  27. // First search for the exact file name in the current
  28. // directory. If that's not found, look for same base name
  29. // with ".com", ".exe" and ".bat" appended, in that order.
  30. // If we can't find it in the current directory, repeat
  31. // the entire process on directories specified in the
  32. // PATH environment variable.
  33. //
  34. #define elements(array) (sizeof(array)/sizeof(array[0]))
  35.  
  36. static wchar_t *extensions[] = {L".com", L".exe", L".bat", L".cmd"};
  37.  
  38. if (-1 != _waccess(name.c_str(), 0))
  39. return name;
  40.  
  41. for (int i=0; i<elements(extensions); i++)
  42. if (-1 != _waccess((name+extensions[i]).c_str(), 0))
  43. return name+extensions[i];
  44.  
  45. wchar_t buffer[FILENAME_MAX];
  46.  
  47. _wsearchenv(name.c_str(), L"PATH", buffer);
  48. if ( buffer[0] != L'\0')
  49. return std::wstring(buffer);
  50.  
  51. for (int i=0; i<elements(extensions); i++) {
  52. _wsearchenv((name+extensions[i]).c_str(), L"PATH", buffer);
  53. if ( buffer[0] != L'\0')
  54. return std::wstring(buffer);
  55. }
  56. return std::wstring(L"");
  57. }
  58.  
  59. class args {
  60. std::vector<std::wstring> arguments;
  61. public:
  62. args() {
  63. wchar_t *cmd_line = GetCommandLineW();
  64. int argc;
  65.  
  66. wchar_t **args = CommandLineToArgvW(cmd_line, &argc);
  67.  
  68. for (int i=0; i<argc; i++)
  69. arguments.push_back(args[i]);
  70. LocalFree(args);
  71. }
  72.  
  73. // args[0] = timer
  74. // args[1] = command to execute
  75. // remaining args = args to command to execute
  76. std::wstring command() const {
  77. std::wstring image = find_image(arguments[1]);
  78. return image;
  79. }
  80.  
  81. std::wstring arg_list() const {
  82. if (arguments.size() < 3)
  83. return std::wstring(L"");
  84.  
  85. std::wostringstream buffer;
  86.  
  87. for (int i=1; i<arguments.size(); i++)
  88. buffer << L"\"" << arguments[i] << L"\" ";
  89. return buffer.str();
  90. }
  91. };
  92.  
  93. HANDLE spawn(args const &a) {
  94. PROCESS_INFORMATION p = {0};
  95. STARTUPINFOW s = {0};
  96.  
  97. if (a.command().empty())
  98. return INVALID_HANDLE_VALUE;
  99.  
  100. wchar_t buffer[FILENAME_MAX] = {0};
  101.  
  102. std::wstring arg_list = a.arg_list();
  103. if (!arg_list.empty())
  104. std::copy(arg_list.begin(), arg_list.end(), buffer);
  105.  
  106. if (!CreateProcessW(a.command().c_str(), buffer, NULL, NULL, TRUE,
  107. NORMAL_PRIORITY_CLASS, NULL, NULL, &s, &p))
  108. {
  109. system_error(L"Spawning program");
  110. return INVALID_HANDLE_VALUE;
  111. }
  112. WaitForSingleObject(p.hProcess, INFINITE);
  113. return p.hProcess;
  114. }
  115.  
  116. FILETIME operator-(FILETIME const &a, FILETIME const &b) {
  117. FILETIME ret;
  118. ret.dwHighDateTime = a.dwHighDateTime - b.dwHighDateTime;
  119. ret.dwLowDateTime = a.dwLowDateTime - b.dwLowDateTime;
  120. return ret;
  121. }
  122.  
  123. std::wostream &operator<<(std::wostream &os, FILETIME const &a) {
  124. long long interval = a.dwLowDateTime | ((long long)a.dwHighDateTime << 32);
  125. return os << (double)interval / 10000000.0;
  126. }
  127.  
  128. int main(void) {
  129. HANDLE child = spawn(args());
  130.  
  131. if (child == INVALID_HANDLE_VALUE) {
  132. std::wcerr << L"Unable to spawn: " << args().command() << L"\n";
  133. return EXIT_FAILURE;
  134. }
  135.  
  136. FILETIME creation_time, exit_time, kernel_time, user_time;
  137. GetProcessTimes(child, &creation_time, &exit_time, &kernel_time, &user_time);
  138.  
  139. std::wcout << L"\n\nReal\t" << exit_time - creation_time << L"\n";
  140. std::wcout << L"User\t" << user_time << L"\n";
  141. std::wcout << L"Sys\t" << kernel_time << L"\n";
  142.  
  143. return 0;
  144. }
  145.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:2:21: error: Windows.h: No such file or directory
prog.cpp:3:22: error: ShellAPI.h: No such file or directory
prog.cpp:4:16: error: io.h: No such file or directory
prog.cpp:10: warning: ignoring #pragma comment 
prog.cpp: In function ‘void system_error(wchar_t*)’:
prog.cpp:18: error: ‘FORMAT_MESSAGE_ALLOCATE_BUFFER’ was not declared in this scope
prog.cpp:19: error: ‘FORMAT_MESSAGE_FROM_SYSTEM’ was not declared in this scope
prog.cpp:20: error: ‘GetLastError’ was not declared in this scope
prog.cpp:20: error: ‘FormatMessageW’ was not declared in this scope
prog.cpp:22: error: ‘LocalFree’ was not declared in this scope
prog.cpp: In function ‘std::wstring find_image(const std::wstring&)’:
prog.cpp:36: warning: deprecated conversion from string constant to ‘wchar_t*’
prog.cpp:36: warning: deprecated conversion from string constant to ‘wchar_t*’
prog.cpp:36: warning: deprecated conversion from string constant to ‘wchar_t*’
prog.cpp:36: warning: deprecated conversion from string constant to ‘wchar_t*’
prog.cpp:38: error: ‘_waccess’ was not declared in this scope
prog.cpp:41: warning: comparison between signed and unsigned integer expressions
prog.cpp:42: error: ‘_waccess’ was not declared in this scope
prog.cpp:47: error: ‘_wsearchenv’ was not declared in this scope
prog.cpp:51: warning: comparison between signed and unsigned integer expressions
prog.cpp: In constructor ‘args::args()’:
prog.cpp:63: error: ‘GetCommandLineW’ was not declared in this scope
prog.cpp:66: error: ‘CommandLineToArgvW’ was not declared in this scope
prog.cpp:70: error: ‘LocalFree’ was not declared in this scope
prog.cpp: In member function ‘std::wstring args::arg_list() const’:
prog.cpp:87: warning: comparison between signed and unsigned integer expressions
prog.cpp: At global scope:
prog.cpp:93: error: ‘HANDLE’ does not name a type
prog.cpp:116: error: expected constructor, destructor, or type conversion before ‘operator’
prog.cpp:123: error: ‘FILETIME’ has not been declared
prog.cpp: In function ‘std::wostream& operator<<(std::wostream&, const int&)’:
prog.cpp:124: error: request for member ‘dwLowDateTime’ in ‘a’, which is of non-class type ‘const int’
prog.cpp:124: error: request for member ‘dwHighDateTime’ in ‘a’, which is of non-class type ‘const int’
prog.cpp: In function ‘int main()’:
prog.cpp:129: error: ‘HANDLE’ was not declared in this scope
prog.cpp:129: error: expected `;' before ‘child’
prog.cpp:131: error: ‘child’ was not declared in this scope
prog.cpp:131: error: ‘INVALID_HANDLE_VALUE’ was not declared in this scope
prog.cpp:136: error: ‘FILETIME’ was not declared in this scope
prog.cpp:136: error: expected `;' before ‘creation_time’
prog.cpp:137: error: ‘child’ was not declared in this scope
prog.cpp:137: error: ‘creation_time’ was not declared in this scope
prog.cpp:137: error: ‘exit_time’ was not declared in this scope
prog.cpp:137: error: ‘kernel_time’ was not declared in this scope
prog.cpp:137: error: ‘user_time’ was not declared in this scope
prog.cpp:137: error: ‘GetProcessTimes’ was not declared in this scope
stdout
Standard output is empty