2 * Helper program for killing lingering python[_d].exe processes before
3 * building, thus attempting to avoid build failures due to files being
12 #pragma comment(lib, "psapi")
15 #define PYTHON_EXE (L"python_d.exe")
16 #define PYTHON_EXE_LEN (12)
17 #define KILL_PYTHON_EXE (L"kill_python_d.exe")
18 #define KILL_PYTHON_EXE_LEN (17)
20 #define PYTHON_EXE (L"python.exe")
21 #define PYTHON_EXE_LEN (10)
22 #define KILL_PYTHON_EXE (L"kill_python.exe")
23 #define KILL_PYTHON_EXE_LEN (15)
27 main(int argc
, char **argv
)
29 HANDLE hp
, hsp
, hsm
; /* process, snapshot processes, snapshot modules */
32 wchar_t path
[MAX_PATH
+1];
37 me
.dwSize
= sizeof(MODULEENTRY32W
);
38 pe
.dwSize
= sizeof(PROCESSENTRY32W
);
40 memset(path
, 0, MAX_PATH
+1);
42 our_pid
= GetCurrentProcessId();
44 hsm
= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE
, our_pid
);
45 if (hsm
== INVALID_HANDLE_VALUE
) {
46 printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError());
50 if (!Module32FirstW(hsm
, &me
)) {
51 printf("Module32FirstW[1] failed: %d\n", GetLastError());
57 * Enumerate over the modules for the current process in order to find
58 * kill_process[_d].exe, then take a note of the directory it lives in.
61 if (_wcsnicmp(me
.szModule
, KILL_PYTHON_EXE
, KILL_PYTHON_EXE_LEN
))
64 len
= wcsnlen_s(me
.szExePath
, MAX_PATH
) - KILL_PYTHON_EXE_LEN
;
65 wcsncpy_s(path
, MAX_PATH
+1, me
.szExePath
, len
);
69 } while (Module32NextW(hsm
, &me
));
74 printf("failed to discern directory of running process\n");
79 * Take a snapshot of system processes. Enumerate over the snapshot,
80 * looking for python processes. When we find one, verify it lives
81 * in the same directory we live in. If it does, kill it. If we're
82 * unable to kill it, treat this as a fatal error and return 1.
84 * The rationale behind this is that we're called at the start of the
85 * build process on the basis that we'll take care of killing any
86 * running instances, such that the build won't encounter permission
87 * denied errors during linking. If we can't kill one of the processes,
88 * we can't provide this assurance, and the build shouldn't start.
91 hsp
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
92 if (hsp
== INVALID_HANDLE_VALUE
) {
93 printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError());
97 if (!Process32FirstW(hsp
, &pe
)) {
98 printf("Process32FirstW failed: %d\n", GetLastError());
103 dac
= PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
| PROCESS_TERMINATE
;
107 * XXX TODO: if we really wanted to be fancy, we could check the
108 * modules for all processes (not just the python[_d].exe ones)
109 * and see if any of our DLLs are loaded (i.e. python31[_d].dll),
110 * as that would also inhibit our ability to rebuild the solution.
111 * Not worth loosing sleep over though; for now, a simple check
112 * for just the python executable should be sufficient.
115 if (_wcsnicmp(pe
.szExeFile
, PYTHON_EXE
, PYTHON_EXE_LEN
))
116 /* This isn't a python process. */
119 /* It's a python process, so figure out which directory it's in... */
120 hsm
= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE
, pe
.th32ProcessID
);
121 if (hsm
== INVALID_HANDLE_VALUE
)
123 * If our module snapshot fails (which will happen if we don't own
124 * the process), just ignore it and continue. (It seems different
125 * versions of Windows return different values for GetLastError()
126 * in this situation; it's easier to just ignore it and move on vs.
127 * stopping the build for what could be a false positive.)
131 if (!Module32FirstW(hsm
, &me
)) {
132 printf("Module32FirstW[2] failed: %d\n", GetLastError());
139 if (_wcsnicmp(me
.szModule
, PYTHON_EXE
, PYTHON_EXE_LEN
))
140 /* Wrong module, we're looking for python[_d].exe... */
143 if (_wcsnicmp(path
, me
.szExePath
, len
))
144 /* Process doesn't live in our directory. */
147 /* Python process residing in the right directory, kill it! */
148 hp
= OpenProcess(dac
, FALSE
, pe
.th32ProcessID
);
150 printf("OpenProcess failed: %d\n", GetLastError());
156 if (!TerminateProcess(hp
, 1)) {
157 printf("TerminateProcess failed: %d\n", GetLastError());
167 } while (Module32NextW(hsm
, &me
));
171 } while (Process32NextW(hsp
, &pe
));
178 /* vi: set ts=8 sw=4 sts=4 expandtab */