D Paste by Clay Smith
Description: Create Process
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | module createprocess; import windows; import std.string; import std.signals; import globals; /// run new program as child process and return the exit code of the program when it's finished uint execProcess(char[] program, char[] args, bool requireExitCode=true) { uint retcode; LPCTSTR lpApplicationName = .toStringz(program); LPCTSTR lpCommandLine = .toStringz(" " ~ args); LPCTSTR lpCurrentDirectory = .toStringz(globals.programDir); // collect startup info STARTUPINFOA startup; GetStartupInfoA(&startup); startup.dwFlags = STARTF_USESTDHANDLES; startup.cb = STARTUPINFOA.sizeof; PROCESS_INFORMATION* info = new PROCESS_INFORMATION(); if (CreateProcessA(lpApplicationName, lpCommandLine, null, null, false, CREATE_NEW_CONSOLE, null,null, &startup, info) != 0) { GetExitCodeProcess(info.hProcess, &retcode); // wait for the program to finish to get the exit code of the program if (requireExitCode) { // while loop until program is done while (retcode == STILL_ACTIVE) { GetExitCodeProcess(info.hProcess, &retcode); Sleep(100); } } CloseHandle(info.hProcess); CloseHandle(info.hThread); return retcode; } return 0; } // Hook ChildProcess up to a timer so that process is called once every .5 seconds, // which the only thing it will really do is to call the return code emitter if it is found class ChildProcesses { // process all processes void process() { // process each process to emit the return code if it has it foreach(char[] key; processes.keys) { uint retcode = 0; // get the state of the process GetExitCodeProcess(processes[key].process.info.hProcess, &retcode); // if the process is still running, just let it run if (retcode == STILL_ACTIVE) { processes[key].running = true; } // process is done running and we havn't gotten the return code, get the return code else if (!processes[key].hasRetCode) { processes[key].running = false; processes[key].process.emit(retcode); processes[key].hasRetCode = true; processes[key].started = false; processes[key].retCode = retcode; // close program handles CloseHandle(processes[key].process.info.hProcess); CloseHandle(processes[key].process.info.hThread); } } } // start process identified by program name with arguments void start(char[] progName, char[] args, void delegate(int) retCodeCall) { // our key will be combo of program and arg names char[] key = progName ~ args; Process p; // store program name so we can easily kill it p.programName = progName; // init our class p.process = new PHandle; // set program name, args, and current directory p.process.lpApplicationName = .toStringz(progName); p.process.lpCommandLine = .toStringz(" " ~ args); p.process.lpCurrentDirectory = .toStringz(globals.programDir); // get startup information GetStartupInfoA(&p.process.startup); p.process.startup.dwFlags = STARTF_USESTDHANDLES; p.process.startup.cb = STARTUPINFOA.sizeof; // create new process information p.process.info = new PROCESS_INFORMATION(); // start running the new process CreateProcessA(p.process.lpApplicationName, p.process.lpCommandLine, null, null, false, CREATE_NEW_CONSOLE, null,null, &p.process.startup, p.process.info); p.started = true; // hook up code that will do something with our return function p.process.retCodeSignal.connect(retCodeCall); p.hasRetCode = false; // add it to our associative array processes[key] = p; } // simply terminate all running processes void terminateAll() { foreach(char[] key; processes.keys) { terminate(key); } } // terminate process identified by program name with arguments void terminate(char[] key) { uint retcode = 0; // get it's exit code and then terminate the process GetExitCodeProcess(processes[key].process.info.hProcess, &retcode); TerminateProcess(processes[key].process.info.hProcess, retcode); // close program handles CloseHandle(processes[key].process.info.hProcess); CloseHandle(processes[key].process.info.hThread); } // all information about a process is stored here class PHandle { LPCTSTR lpApplicationName; LPCTSTR lpCommandLine; LPCTSTR lpCurrentDirectory; STARTUPINFOA startup; PROCESS_INFORMATION* info; mixin Signal!(int) retCodeSignal; // signal emitted when found the return code } struct Process { bool started = false; // whether or not process was started bool running = false; // whether or not process is running int retCode=0; // return code of the process bool hasRetCode = false; // whether or not process has the proper return code PHandle process; // process information structure char[] programName; } // store in an assoc array Process[char[]] processes; } |