Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in tip

fogcreek terminate: wait for process to terminate instead of for a fixed amount of time

Changeset 382d36b80598

Parent 89203f4e871a

by David Golub

Changes to one file · Browse files at 382d36b80598 Showing diff from parent 89203f4e871a Diff from another changeset...

 
17
18
19
20
 
21
 
 
 
 
 
22
23
24
 
 
 
 
25
26
27
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
31
 
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
@@ -17,15 +17,52 @@
   #include "THgStatus.h"   -// terminates the overlay icon server +#include <tlhelp32.h>   +#define TIMEOUT_VALUE 5000 +#define EXECUTABLE_NAME "TortoiseHgOverlayServer.exe" + +// This library implements a custom action for Windows Installer that terminates +// the overlay icon server.  extern "C" UINT __stdcall TerminateIconServer()  { - if (CTHgStatus::Terminate() == 0) + // Enumerate processes to attempt to find the overlay icon server. + HANDLE hProcess = NULL; + HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0L); + if (hSnapshot != NULL)   { - // pipe ok, so icon server is running - // -> wait a bit for icon server to shut down - ::Sleep(5000 /* ms */); + PROCESSENTRY32 pe; + pe.dwSize = sizeof(PROCESSENTRY32); + if (::Process32First(hSnapshot, &pe)) + { + do + { + CString strExeName(pe.szExeFile); + if (strExeName.CompareNoCase(EXECUTABLE_NAME) == 0) + { + hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, pe.th32ProcessID); + break; + } + } while(::Process32Next(hSnapshot, &pe)); + } + ::CloseHandle(hSnapshot);   } + + // Attempt to terminate the server. + if(CTHgStatus::Terminate() == 0) + { + if (hProcess != NULL) + { + ::WaitForSingleObject(hProcess, TIMEOUT_VALUE); + ::CloseHandle(hProcess); + } + else + { + // If a process handle is not available but the server was running, + // stall for a brief time to allow the server to terminate. + ::Sleep(TIMEOUT_VALUE); + } + } +   return ERROR_SUCCESS;  }