程序流程如下:
- 记录下正在运行的IIS相关服务(这样可以避免在步骤3启动原本服务器上并未开启的服务)
- 停止上述服务
- 开启上述服务
可以在步骤2和步骤3之间做一些事情。
#ifndef __IIS_RESET_H__
#define __IIS_RESET_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _IIS_RESET* iisreset_t;
iisreset_t InitializeIisReset();
int GetRunningIisLinkedServices(iisreset_t IisReset);
int StopIisLinkedServices(iisreset_t IisReset);
int StartIisLinkedServices(iisreset_t IisReset);
void ReleaseIisReset(iisreset_t IisReset);
#ifdef __cplusplus
}
#endif
#endif
#include "iis_service.h"
#include <iisrsta.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
typedef struct _SERVICE_ITEM
{
LIST_ENTRY Entry;
CHAR ServiceName[128];
}SERVICE_ITEM, * PSERVICE_ITEM;
typedef struct _IIS_RESET
{
LIST_ENTRY RunningServicesList;
BOOL IisIsRunning;
}IIS_RESET, * PIIS_RESET;
BOOL PathHas_inetsrv(HKEY hKey, PCSTR ValueName)
{
DWORD ValueType;
CHAR PathName[MAX_PATH];
DWORD cbPathName;
BOOL RetVal = FALSE;
do
{
cbPathName = sizeof(PathName);
if (RegQueryValueExA(hKey, ValueName, NULL, &ValueType, (LPBYTE)&PathName, &cbPathName) != ERROR_SUCCESS)
break;
if (ValueType != REG_EXPAND_SZ && ValueType != REG_SZ)
break;
if (cbPathName == 0)
break;
if (StrStrIA(PathName, "inetsrv\\"))
RetVal = TRUE;
} while (0);
return RetVal;
}
BOOL ServiceIsRunning(PCSTR ServiceName)
{
SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
SERVICE_STATUS ServiceStatus;
BOOL Ret = FALSE;
do
{
hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
if (hSCManager == NULL)
break;
hService = OpenServiceA(hSCManager, ServiceName, SERVICE_QUERY_STATUS);
if (hService == NULL)
break;
do
{
if (QueryServiceStatus(hService, &ServiceStatus) == FALSE)
break;
if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
Ret = TRUE;
} while (ServiceStatus.dwCurrentState == SERVICE_START_PENDING);
} while (0);
if (hService)
CloseServiceHandle(hService);
if (hSCManager)
CloseServiceHandle(hSCManager);
return Ret;
}
BOOL EasyStartService(LPCSTR ServiceName)
{
SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
SERVICE_STATUS ServiceStatus;
BOOL Ret = FALSE;
do
{
hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
if (hSCManager == NULL)
break;
hService = OpenServiceA(hSCManager, ServiceName, SERVICE_START | SERVICE_QUERY_STATUS);
if (hService == NULL)
break;
if (StartServiceA(hService, 0, NULL) == FALSE)
break;
do
{
if (QueryServiceStatus(hService, &ServiceStatus) == FALSE)
break;
if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
Ret = TRUE;
} while (ServiceStatus.dwCurrentState == SERVICE_START_PENDING);
} while (0);
if (hService)
CloseServiceHandle(hService);
if (hSCManager)
CloseServiceHandle(hSCManager);
return Ret;
}
BOOL EasyStopService(LPCSTR ServiceName)
{
SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
SERVICE_STATUS ServiceStatus;
BOOL Ret = FALSE;
do
{
hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
if (hSCManager == NULL)
break;
hService = OpenServiceA(hSCManager, ServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS);
if (hService == NULL)
break;
if (ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus) == FALSE)
break;
if (ServiceStatus.dwCurrentState == SERVICE_STOPPED)
Ret = TRUE;
while (ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
if (QueryServiceStatus(hService, &ServiceStatus) == FALSE)
break;
if (ServiceStatus.dwCurrentState == SERVICE_STOPPED)
Ret = TRUE;
}
} while (0);
if (hService)
CloseServiceHandle(hService);
if (hSCManager)
CloseServiceHandle(hSCManager);
return Ret;
}
const IID IID_IIisServiceControl =
{ 0x0E8FB8620, 0x588F, 0x11D2,
{ 0x9D, 0x61, 0x00, 0xC0, 0x4F, 0x79, 0xC5, 0xFE } };
const GUID CLSID_IisServiceControl =
{ 0x0E8FB8621, 0x588F, 0x11D2,
{ 0x9D, 0x61, 0x00, 0xC0, 0x4F, 0x79, 0xC5, 0xFE } };
int StopW3SVC()
{
HRESULT result;
int rc = -1;
IIisServiceControl* IisSrvCtrl = NULL;
result = CoInitializeEx(0, 0);
if (result != S_OK)
return 1;
do
{
result = CoCreateInstance(&CLSID_IisServiceControl,
NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER | CLSCTX_INPROC_SERVER,
&IID_IIisServiceControl,
(LPVOID*)&IisSrvCtrl
);
if (result != S_OK)
{
rc = 2;
break;
}
//如果IIS服务本身就是关闭状态,调用Stop函数返回的也是S_OK
result = IisSrvCtrl->lpVtbl->Stop(IisSrvCtrl, 60 * 1000, TRUE);
if (result != S_OK)
{
rc = 3;
break;
}
rc = 0;
} while (0);
CoUninitialize();
return rc;
}
int StartW3SVC()
{
HRESULT result;
int rc = -1;
IIisServiceControl* IisSrvCtrl = NULL;
result = CoInitializeEx(0, 0);
if (result != S_OK)
return 1;
do
{
result = CoCreateInstance(&CLSID_IisServiceControl,
NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER | CLSCTX_INPROC_SERVER,
&IID_IIisServiceControl,
(LPVOID*)&IisSrvCtrl
);
if (result != S_OK)
{
rc = 2;
break;
}
result = IisSrvCtrl->lpVtbl->Start(IisSrvCtrl, 60 * 1000);
if (S_OK != result)
{
rc = 3;
break;
}
rc = 0;
} while (0);
CoUninitialize();
return rc;
}
int GetRunningIisLinkedServices(iisreset_t IisReset)
{
LSTATUS RetVal;
HKEY hServiceListKey = NULL;
HKEY hServiceKey = NULL;
HKEY hParametersKey = NULL;
CHAR Name[128];
DWORD cchName;
DWORD ValueType;
DWORD Type;
DWORD cbType;
PSERVICE_ITEM ServiceItem;
PLIST_ENTRY Blink;
int RunningCount = -1;
RetVal = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services",
0L, KEY_ENUMERATE_SUB_KEYS,
&hServiceListKey
);
if (RetVal != ERROR_SUCCESS)
{
return RunningCount;
}
for (int i = 0;; i++)
{
cchName = sizeof(Name);
RetVal = RegEnumKeyExA(hServiceListKey, i, Name, &cchName,
NULL, NULL, NULL, NULL);
if (RetVal != ERROR_SUCCESS)
{
if (RetVal == ERROR_NO_MORE_ITEMS)
{
}
break;
}
RetVal = RegOpenKeyExA(hServiceListKey, Name, 0, KEY_READ, &hServiceKey);
if (RetVal != ERROR_SUCCESS)
continue;
do
{
cbType = sizeof(Type);
RetVal = RegQueryValueExA(hServiceKey, "Type", NULL, &ValueType, (LPBYTE)&Type, &cbType);
if (RetVal != ERROR_SUCCESS)
break;
if (ValueType != REG_DWORD || cbType != sizeof(DWORD))
break;
if (Type & SERVICE_WIN32_SHARE_PROCESS)
{
RetVal = RegOpenKeyExA(hServiceKey, "Parameters", 0, KEY_READ, &hParametersKey);
if (RetVal != ERROR_SUCCESS)
break;
}
if (PathHas_inetsrv(hParametersKey ? hParametersKey : hServiceKey,
hParametersKey ? "ServiceDll" : "ImagePath") == FALSE
) {
break;
}
if (ServiceIsRunning(Name) == FALSE)
break;
if (lstrcmpiA(Name, "W3SVC") == 0)
{
IisReset->IisIsRunning = TRUE;
break;
}
ServiceItem = LocalAlloc(LPTR, sizeof(SERVICE_ITEM));
if (ServiceItem == NULL)
break;
lstrcpyA(ServiceItem->ServiceName, Name);
Blink = IisReset->RunningServicesList.Blink;
ServiceItem->Entry.Flink = &IisReset->RunningServicesList;
ServiceItem->Entry.Blink = Blink;
Blink->Flink = &ServiceItem->Entry;
IisReset->RunningServicesList.Blink = &ServiceItem->Entry;
RunningCount++;
} while (0);
if (hParametersKey)
{
RegCloseKey(hParametersKey);
hParametersKey = NULL;
}
if (hServiceKey)
{
RegCloseKey(hServiceKey);
hServiceKey = NULL;
}
}
RegCloseKey(hServiceListKey);
return RunningCount;
}
int StopIisLinkedServices(iisreset_t IisReset)
{
PLIST_ENTRY Entry;
PSERVICE_ITEM ServiceItem;
int StoppedCount = 0;
if (IisReset->IisIsRunning)
{
StopW3SVC();
}
Entry = IisReset->RunningServicesList.Flink;
while (Entry != &IisReset->RunningServicesList)
{
ServiceItem = CONTAINING_RECORD(Entry, SERVICE_ITEM, Entry);
if (EasyStopService(ServiceItem->ServiceName))
StoppedCount++;
Entry = Entry->Flink;
}
return StoppedCount;
}
int StartIisLinkedServices(iisreset_t IisReset)
{
PLIST_ENTRY Entry;
PSERVICE_ITEM ServiceItem;
int StartedCount = 0;
if (IisReset->IisIsRunning)
{
StartW3SVC();
}
Entry = IisReset->RunningServicesList.Flink;
while (Entry != &IisReset->RunningServicesList)
{
ServiceItem = CONTAINING_RECORD(Entry, SERVICE_ITEM, Entry);
if (EasyStartService(ServiceItem->ServiceName))
StartedCount++;
Entry = Entry->Flink;
}
return StartedCount;
}
iisreset_t InitializeIisReset()
{
PIIS_RESET IisReset = LocalAlloc(LPTR, sizeof(IIS_RESET));
if (IisReset == NULL)
return NULL;
IisReset->RunningServicesList.Flink = IisReset->RunningServicesList.Blink = &IisReset->RunningServicesList;
IisReset->IisIsRunning = TRUE;
return IisReset;
}
void ReleaseIisReset(iisreset_t IisReset)
{
PLIST_ENTRY Entry;
PSERVICE_ITEM ServiceItem;
Entry = IisReset->RunningServicesList.Flink;
while (Entry != &IisReset->RunningServicesList)
{
ServiceItem = CONTAINING_RECORD(Entry, SERVICE_ITEM, Entry);
Entry = Entry->Flink;
LocalFree(ServiceItem);
}
LocalFree(IisReset);
}
#include "iis_service.h"
int main(int argc, char* argv[])
{
iisreset_t IisReset = InitializeIisReset();
GetRunningIisLinkedServices(IisReset);
StopIisLinkedServices(IisReset);
//
//do work
//
StartIisLinkedServices(IisReset);
ReleaseIisReset(IisReset);
return 0;
}
发表回复