首页 > 解决方案 > 检查 Windows 应用程序是否作为服务运行

问题描述

有没有办法确定 Windows 进程是否作为服务运行?是否有我可以识别的所有服务的任何固定父进程以确保该进程是服务进程。

标签: winapi

解决方案


如果应用程序设计为既作为服务运行又作为独立应用程序运行,了解应用程序如何启动的最佳方法 - 使用命令行。当您使用CreateServiceW注册服务时 - 将一些参数传递给lpBinaryPathName 。然后在开始时 - 检查GetCommandLineW()返回的字符串- 此参数是否存在。如果是 - 你作为服务运行,如果不是 - 作为独立应用程序。

例如将\n符号附加到服务二进制文件路径:

WCHAR BinaryPathName[MAX_PATH + 3];
ULONG cch = GetModuleFileNameW(0, BinaryPathName + 1, _countof(BinaryPathName) - 3);
if (GetLastError() == NOERROR)
{
    BinaryPathName[0] = '\"';
    BinaryPathName[cch + 1] = '\"';
    BinaryPathName[cch + 2] = '\n';
    BinaryPathName[cch + 3] = 0;
    //CreateServiceW(.., BinaryPathName, ..);
}

\n选择此符号是因为如果手动执行应用程序,此符号不能在命令行中

然后在应用程序入口点做非常简单快速的检查

if (wcschr(GetCommandLineW(), '\n'))
{
    const static SERVICE_TABLE_ENTRY ste[] = { { L"my_service_name", ServiceMain }, {} };
    StartServiceCtrlDispatcher(ste);
}
else 
{
  // run as standalone application
}

我认为这个解决方案是最好的。然而可能和其他人。例如我们可以做下一个检查:

ULONG SessionId;
if (ProcessIdToSessionId(GetCurrentProcessId(), &SessionId) && 
    WTSGetActiveConsoleSessionId() == SessionId)
{
    // we not run as service;
}

推荐阅读