MT5APIProcess.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. //+------------------------------------------------------------------+
  2. //| MetaTrader 5 |
  3. //| Copyright 2000-2019, MetaQuotes Software Corp. |
  4. //| http://www.metaquotes.net |
  5. //+------------------------------------------------------------------+
  6. #pragma once
  7. #include <windows.h>
  8. #include "MT5APIStr.h"
  9. //+------------------------------------------------------------------+
  10. //| Process manipulation class |
  11. //+------------------------------------------------------------------+
  12. class CMTProcess
  13. {
  14. HANDLE m_process;
  15. HANDLE m_thread;
  16. HANDLE m_std_write;
  17. HANDLE m_std_read;
  18. DWORD m_process_id;
  19. DWORD m_thread_id;
  20. public:
  21. CMTProcess() : m_process(NULL),m_thread(NULL),m_std_write(NULL),m_std_read(NULL),m_process_id(0),m_thread_id(0) {};
  22. ~CMTProcess() { Close(); }
  23. //--- process manipulation
  24. bool Start(CMTStr &command,const DWORD flags=DETACHED_PROCESS,const bool inherit=false);
  25. void Close(void);
  26. DWORD Read(void *buffer,const DWORD length);
  27. bool Priority(DWORD priority_class);
  28. bool Wait(const DWORD timeout=INFINITE);
  29. DWORD ThreadID(void) const { return(m_thread_id); }
  30. DWORD ExitCode(void);
  31. void Terminate(void);
  32. };
  33. //+------------------------------------------------------------------+
  34. //| Process start |
  35. //+------------------------------------------------------------------+
  36. inline bool CMTProcess::Start(CMTStr &command,const DWORD flags/*=CREATE_NO_WINDOW*/,const bool inherit/*=false*/)
  37. {
  38. STARTUPINFOW si={0};
  39. PROCESS_INFORMATION pi={0};
  40. SECURITY_ATTRIBUTES sa={ sizeof(sa),NULL,TRUE };
  41. HANDLE read_handle,process=::GetCurrentProcess();
  42. //--- close previous
  43. Close();
  44. //--- intercept in\out for console threads
  45. if(flags&CREATE_NEW_CONSOLE)
  46. {
  47. //--- create pipe for in\out interception
  48. if(::CreatePipe(&read_handle,&m_std_write,&sa,0))
  49. {
  50. //--- create new read handle
  51. ::DuplicateHandle(process,read_handle,process,&m_std_read,0,FALSE,DUPLICATE_SAME_ACCESS);
  52. ::CloseHandle(read_handle);
  53. read_handle=NULL;
  54. //--- fill structure
  55. si.cb =sizeof(si);
  56. si.dwFlags =STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  57. si.hStdOutput =m_std_write;
  58. si.hStdInput =NULL;
  59. si.hStdError =m_std_write;
  60. si.wShowWindow=SW_HIDE;
  61. }
  62. }
  63. //--- create process
  64. if(CreateProcessW(NULL,command.Buffer(),NULL,NULL,inherit ? TRUE:FALSE,flags,NULL,NULL,&si,&pi)==FALSE)
  65. return(false);
  66. //---
  67. m_process =pi.hProcess;
  68. m_process_id=pi.dwProcessId;
  69. m_thread =pi.hThread;
  70. m_thread_id =pi.dwThreadId;
  71. //--- ok
  72. return(true);
  73. }
  74. //+------------------------------------------------------------------+
  75. //| Process close |
  76. //+------------------------------------------------------------------+
  77. inline void CMTProcess::Close(void)
  78. {
  79. //--- close in\out handles
  80. if(m_std_write!=NULL) { CloseHandle(m_std_write); m_std_write=NULL; }
  81. if(m_std_read!=NULL) { CloseHandle(m_std_read); m_std_read=NULL; }
  82. //--- close process handle
  83. if(m_process!=NULL) { CloseHandle(m_process); m_process=NULL; m_process_id=0; }
  84. //--- close process thread handle
  85. if(m_thread !=NULL) { CloseHandle(m_thread); m_thread=NULL; m_thread_id=0; }
  86. }
  87. //+------------------------------------------------------------------+
  88. //| Read stdread |
  89. //+------------------------------------------------------------------+
  90. inline DWORD CMTProcess::Read(void *buffer,const DWORD length)
  91. {
  92. DWORD readed=0;
  93. //--- check
  94. if(m_std_write==NULL || m_std_read==NULL || m_process==NULL || buffer==NULL || length<1) return(0);
  95. //--- read
  96. if(::ReadFile(m_std_read,buffer,length,&readed,NULL)==0) readed=0;
  97. //--- read result
  98. return(readed);
  99. }
  100. //+------------------------------------------------------------------+
  101. //| Priority |
  102. //+------------------------------------------------------------------+
  103. inline bool CMTProcess::Priority(DWORD priority_class)
  104. {
  105. return(m_process && SetPriorityClass(m_process,priority_class));
  106. }
  107. //+------------------------------------------------------------------+
  108. //| Process wait |
  109. //+------------------------------------------------------------------+
  110. inline bool CMTProcess::Wait(const DWORD timeout/*=INFINITE*/)
  111. {
  112. //--- checks
  113. if(m_process==NULL) return(false);
  114. //--- waiting
  115. DWORD res=WaitForSingleObject(m_process,timeout);
  116. if(res==WAIT_OBJECT_0)
  117. return(true);
  118. //--- fail
  119. return(false);
  120. }
  121. //+------------------------------------------------------------------+
  122. //| Process exit code |
  123. //+------------------------------------------------------------------+
  124. inline DWORD CMTProcess::ExitCode(void)
  125. {
  126. DWORD exitCode=0;
  127. //--- checks
  128. if(m_process!=NULL)
  129. {
  130. //--- exit code
  131. GetExitCodeProcess(m_process,&exitCode);
  132. }
  133. //--- result
  134. return(exitCode);
  135. }
  136. //+------------------------------------------------------------------+
  137. //| Process terminate |
  138. //+------------------------------------------------------------------+
  139. inline void CMTProcess::Terminate(void)
  140. {
  141. //--- check
  142. if(m_process==NULL) return;
  143. //--- do it
  144. TerminateProcess(m_process,0);
  145. //--- close handles
  146. Close();
  147. }
  148. //+------------------------------------------------------------------+