Develop and Download Open Source Software

Browse Subversion Repository

Contents of /CopalPro/KExecProc.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Thu Jul 28 09:05:52 2011 UTC (12 years, 9 months ago) by kaityo
File MIME type: text/x-c++src
File size: 5072 byte(s)
First Commit
1 //---------------------------------------------------------------------------
2 // 子プロセスを起動し、標準入出力を取るクラス
3 //---------------------------------------------------------------------------
4 #include <vcl.h>
5 #pragma hdrstop
6
7 #include "KExecProc.h"
8 //---------------------------------------------------------------------------
9 #pragma package(smart_init)
10
11
12 const int BUFFER_SIZE = 4097;//パイプのバッファサイズ
13 //---------------------------------------------------------------------------
14 /**
15 * コンストラクタ
16 */
17 KExecProc::KExecProc(AnsiString cmd) {
18 kThread = new KThread(true);
19 CommandLine = cmd;
20 msStdOut = new TMemoryStream;//標準出力用
21 msStdErr = new TMemoryStream;//標準エラー用
22 lpEnvironment = NULL;
23 }
24 //---------------------------------------------------------------------------
25 /**
26 * デストラクタ
27 */
28 KExecProc::~KExecProc(void) {
29 if(lpEnvironment != NULL)
30 delete lpEnvironment;
31 delete kThread;
32 delete msStdOut;
33 delete msStdErr;
34 }
35 //---------------------------------------------------------------------------
36 /**
37 * 環境変数データを受け取る
38 */
39 void
40 KExecProc::SetEnvironment(char *b) {
41 if(lpEnvironment != NULL) {
42 ShowMessage("KExecProc::SetEnvironment\nAsertionFailed.");
43 }
44 lpEnvironment = b;
45 }
46 //---------------------------------------------------------------------------
47 /**
48 * 子プロセスを起動する
49 */
50 bool
51 KExecProc::Execute(void) {
52 //実行監視スレッドを立ち上げる
53
54 //SECURITY_ATTRIBUTEの設定
55
56 SECURITY_ATTRIBUTES saStdOut,saStdErr;
57 saStdOut.nLength = sizeof( SECURITY_ATTRIBUTES );
58 saStdOut.bInheritHandle = true;
59 saStdOut.lpSecurityDescriptor = NULL;
60
61 saStdErr.nLength = sizeof( SECURITY_ATTRIBUTES );
62 saStdErr.bInheritHandle = true;
63 saStdErr.lpSecurityDescriptor = NULL;
64
65 //このプロセスのSTDOUT,STDERRハンドルの保存
66 HANDLE hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
67 HANDLE hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
68
69 //子プロセスへのパイプをつくる。
70 HANDLE hStdOutWriteEnd,hStdOutReadEnd;
71 HANDLE hStdErrWriteEnd,hStdErrReadEnd;
72
73 if (!CreatePipe(&hStdOutReadEnd, &hStdOutWriteEnd, &saStdOut, 0)) {
74 SetErrorMessage("Cannot create a Pipe(StdOut)");
75 return false;
76 }
77 if (!CreatePipe(&hStdErrReadEnd, &hStdErrWriteEnd, &saStdErr, 0)) {
78 SetErrorMessage("Cannot create a Pipe(StdErr)");
79 return false;
80 }
81
82 PROCESS_INFORMATION pi;
83 STARTUPINFO si;
84 GetStartupInfo(&si);
85 si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
86 si.wShowWindow = SW_HIDE;
87 si.hStdOutput = hStdOutWriteEnd;
88 si.hStdError = hStdErrWriteEnd;
89
90 //プロセスの作成
91 if (!CreateProcess(NULL,CommandLine.c_str(), NULL, NULL, TRUE, 0, lpEnvironment, NULL, &si, &pi)) {
92 SetErrorMessage("Cannot create a proccess.");
93 return false;
94 }
95 // このプロセスの標準出力を元に戻す。
96 if (!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) {
97 SetErrorMessage("Cannot restore STDOUT");
98 return false;
99 }
100 if (!SetStdHandle(STD_ERROR_HANDLE, hSaveStderr)) {
101 SetErrorMessage("Cannot restore STDERR");
102 return false;
103 }
104 //パイプから読み込む前に書き込み端を閉じる。
105 if ( !CloseHandle( hStdOutWriteEnd) ) {
106 SetErrorMessage("Cannot close stdout write end.");
107 return false;
108 }
109 if ( !CloseHandle( hStdErrWriteEnd) ) {
110 SetErrorMessage("Cannot close stderr write end.");
111 return false;
112 }
113
114 //スレッドにハンドルを渡す
115
116 kThread->SetHandle(pi.hProcess);
117 kThread->Resume();
118
119 //パイプ読み込みの準備
120
121 DWORD exitcode = 1;//終了フラグ
122 char bufStdOut[BUFFER_SIZE],bufStdErr[BUFFER_SIZE];//読み込みbuffer
123 DWORD readbufStdOut = 0,readbufStdErr = 0;//読み込んだバイト数
124
125 SetLastError(-1);
126
127 //ストリームの準備
128 msStdOut->Clear();
129 msStdErr->Clear();
130
131 //プロセスを監視する無限メインループ
132
133 while(1) {
134
135 //exitcodeを調べる
136 if(GetExitCodeProcess(pi.hProcess,&exitcode)==false) {
137 SetErrorMessage("Error:Fail to ExitCodeProcess\n");
138 break;
139 }
140
141 if (exitcode !=STILL_ACTIVE)
142 break;
143
144 if (GetAsyncKeyState(VK_ESCAPE)<0) {
145 ShowMessage("処理は中断されました");
146 break;
147 }
148
149 do {
150 if(!ReadFile(hStdOutReadEnd,bufStdOut,sizeof(bufStdOut),&readbufStdOut,NULL))
151 break;
152 if(readbufStdOut) {
153 msStdOut->Write(bufStdOut,readbufStdOut);
154 }
155 } while(readbufStdOut!=0);
156
157
158 if(!ReadFile(hStdErrReadEnd,bufStdErr,sizeof(bufStdErr),&readbufStdErr,NULL))
159 break;
160 if(readbufStdErr) {
161 msStdErr->Write(bufStdErr,readbufStdErr);
162 }
163 }
164
165 //プロセス終了後の処理
166
167 CloseHandle(hStdOutReadEnd);
168 CloseHandle(hStdErrReadEnd);
169
170 //スレッドを殺す
171 kThread->Terminate();
172
173 if(GetExitCodeProcess(pi.hProcess,&exitcode)==false) {
174 SetErrorMessage("Error:Fail to ExitCodeProcess\n");
175 return false;
176 }
177 ExitCode = exitcode;
178
179 if(ExitCode!=0) {
180 return false;
181 } else {
182 return true;
183 }
184 }
185 //---------------------------------------------------------------------------

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26