32 static TCHAR last_service_name[128];
33 int remove_service(TCHAR *installdir,
int check_only) {
37 if(wcslen(installdir) < 3) {
38 WcaLog(LOGMSG_STANDARD,
"INSTALLDIR is suspiciously short, better not do anything.");
43 WcaLog(LOGMSG_STANDARD,
"Determining number of matching services...");
44 int servicecount = remove_service(installdir, 1);
45 if(servicecount <= 0) {
46 WcaLog(LOGMSG_STANDARD,
"No services found, not removing anything.");
48 }
else if(servicecount == 1) {
50 swprintf_s(buf,
sizeof(buf), TEXT(
"There is a service called '%ls' set up to run from this installation. Do you wish me to stop and remove that service?"), last_service_name);
51 int rc = MessageBox(NULL, buf, TEXT(
"Removing MySQL Server"), MB_ICONQUESTION|MB_YESNOCANCEL|MB_SYSTEMMODAL);
52 if(rc == IDCANCEL)
return -1;
53 if(rc != IDYES)
return 0;
54 }
else if(servicecount > 0) {
56 swprintf_s(buf,
sizeof(buf), TEXT(
"There appear to be %d services set up to run from this installation. Do you wish me to stop and remove those services?"), servicecount);
57 int rc = MessageBox(NULL, buf, TEXT(
"Removing MySQL Server"), MB_ICONQUESTION|MB_YESNOCANCEL|MB_SYSTEMMODAL);
58 if(rc == IDCANCEL)
return -1;
59 if(rc != IDYES)
return 0;
63 if(check_only == -1) check_only = 0;
65 WcaLog(LOGMSG_STANDARD,
"Looking for service...");
66 WcaLog(LOGMSG_STANDARD,
"INSTALLDIR = %ls", installdir);
67 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT(
"SYSTEM\\CurrentControlSet\\services"), 0, KEY_READ, &hKey)==ERROR_SUCCESS) {
70 DWORD keylen =
sizeof(keyname);
73 while(RegEnumKeyExW(hKey, index, keyname, &keylen, NULL, NULL, NULL, &t) == ERROR_SUCCESS) {
76 DWORD pathlen =
sizeof(path)-1;
77 if (RegOpenKeyExW(hKey, keyname, NULL, KEY_READ, &hServiceKey) == ERROR_SUCCESS) {
79 if (RegQueryValueExW(hServiceKey, TEXT(
"ImagePath"), NULL, NULL, (LPBYTE)path, &pathlen) == ERROR_SUCCESS) {
82 if(p[0] ==
'"') p += 1;
84 if(wcsncmp(p, installdir, wcslen(installdir)) == 0) {
85 WcaLog(LOGMSG_STANDARD,
"Found service '%ls' with ImagePath '%ls'.", keyname, path);
86 swprintf_s(last_service_name,
sizeof(last_service_name), TEXT(
"%ls"), keyname);
89 WcaLog(LOGMSG_STANDARD,
"Trying to stop the service.");
90 SC_HANDLE hSCM = NULL;
91 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
93 SC_HANDLE hService = NULL;
94 hService = OpenService(hSCM, keyname, SERVICE_STOP|SERVICE_QUERY_STATUS|DELETE);
95 if(hService != NULL) {
96 WcaLog(LOGMSG_STANDARD,
"Waiting for the service to stop...");
97 SERVICE_STATUS status;
99 if(ControlService(hService, SERVICE_CONTROL_STOP, &status)) {
101 while(
"it's one big, mean and cruel world out there") {
102 if(!QueryServiceStatus(hService, &status))
break;
103 if(status.dwCurrentState == SERVICE_STOPPED)
break;
106 WcaLog(LOGMSG_STANDARD,
"Stopped the service.");
109 DeleteService(hService);
110 CloseServiceHandle(hService);
112 CloseServiceHandle(hSCM);
118 RegCloseKey(hServiceKey);
121 keylen =
sizeof(keyname)-1;
125 WcaLog(LOGMSG_STANDARD,
"Can't seem to go through the list of installed services in the registry.");
130 UINT wrap(MSIHANDLE hInstall,
char *
name,
int check_only) {
132 UINT er = ERROR_SUCCESS;
134 hr = WcaInitialize(hInstall, name);
135 ExitOnFailure(hr,
"Failed to initialize");
137 WcaLog(LOGMSG_STANDARD,
"Initialized.");
139 TCHAR INSTALLDIR[1024];
140 DWORD INSTALLDIR_size =
sizeof(INSTALLDIR);
141 if(MsiGetPropertyW(hInstall, TEXT(
"CustomActionData"), INSTALLDIR, &INSTALLDIR_size) == ERROR_SUCCESS) {
142 int rc = remove_service(INSTALLDIR, check_only);
144 er = ERROR_CANCELLED;
147 er = ERROR_CANT_ACCESS_FILE;
151 return WcaFinalize(er);
154 UINT __stdcall RemoveServiceNoninteractive(MSIHANDLE hInstall)
156 return wrap(hInstall,
"RemoveServiceNoninteractive", -1);
159 UINT __stdcall RemoveService(MSIHANDLE hInstall)
161 return wrap(hInstall,
"RemoveService", 0);
164 UINT __stdcall TestService(MSIHANDLE hInstall)
166 return wrap(hInstall,
"TestService", 1);
170 extern "C" BOOL WINAPI DllMain(
171 __in HINSTANCE hInst,
178 case DLL_PROCESS_ATTACH:
179 WcaGlobalInitialize(hInst);
182 case DLL_PROCESS_DETACH: