如何从Visual C ++获取特定的Windows服务可执行文件路径

时间:2015-09-01 03:40:31

标签: c++ windows winapi visual-c++ windows-services

当我只知道服务名称时,如何从其他程序获取正在运行的Windows服务的可执行文件路径?

2 个答案:

答案 0 :(得分:2)

#include <Psapi.h>
#include <windows.h>
#pragma comment(lib, "psapi.lib")

int wmain() 
{
    //insert your service PID here instead of 404
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, 404);
    if (!hProcess)
        return(0);

    wchar_t szBuffer[MAX_PATH];
    ZeroMemory(szBuffer, sizeof(szBuffer));
    DWORD dwSize = sizeof(szBuffer) / sizeof(szBuffer[0]) - 1;
    QueryFullProcessImageName(hProcess, 0, szBuffer, &dwSize);
    return(0);
}

您必须使用提升的访问系统服务信息的权限启动代码。否则OpenProcess将返回NULLGetLastError将返回ERROR_ACCESS_DENIED代码。

你也可以使用:

  1. GetProcessImageFileName获取系统原生路径 格式;
  2. GetModuleFileNameEx使用NULL模块句柄。
  3. 更新:如果您只有服务名称,那么您必须使用其他方法:

    int wmain()
    {
        LPQUERY_SERVICE_CONFIG lpsc;
    
    
        SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
    
        if (!hSCManager)
            return(0);
    
        SC_HANDLE hService = OpenService(hSCManager, L"Browser", SERVICE_QUERY_CONFIG); 
    
        if (!hService)
        {
            CloseServiceHandle(hSCManager);
            return(0);
        }
    
    
        DWORD dwBytesNeeded = 0, dwBufSize;
        if (!QueryServiceConfig(hService, NULL, 0, &dwBytesNeeded))
        {
            DWORD dwError = GetLastError();
            if (ERROR_INSUFFICIENT_BUFFER == dwError)
            {
                dwBufSize = dwBytesNeeded;
                lpsc = (LPQUERY_SERVICE_CONFIG)HeapAlloc(GetProcessHeap(), 0, dwBufSize);
            }
            else
            {
                CloseServiceHandle(hService);
                CloseServiceHandle(hSCManager);
                return(0);
            }
        }
    
        if (QueryServiceConfig(hService, lpsc, dwBufSize, &dwBytesNeeded))
        {
            //lpsc->lpBinaryPathName contains exe path
        }
    
        HeapFree(GetProcessHeap(), 0, lpsc);
        CloseServiceHandle(hService);
        CloseServiceHandle(hSCManager);
        return(0);
    }
    

答案 1 :(得分:1)

使用QueryServiceConfig()QUERY_SERVICE_CONFIG::lpBinaryPathName字段将报告用于运行服务的完整命令行。

例如:

struct SCHandle
{
private:
    SC_HANDLE hValue;
public:
    SCHandle(SC_HANDLE Value) : hValue(Value) {}
    ~SCHandle() { if (hValue != NULL) CloseServiceHandle(hValue); } 
    operator SC_HANDLE() { return hValue; } 
    bool operator!() const { return (hValue == NULL); } 
};

std::wstring GetServiceBinaryName(const std::wstring &ServiceName)
{
    SCHandle hSCManager(OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT));
    if (!hSCManager)
        return L"";

    SCHandle hService(OpenServiceW(hSCManager, ServiceName.c_str(), SERVICE_QUERY_CONFIG));
    if (!hService)
        return L"";

    std::vector<BYTE> buffer;
    DWORD dwBytesNeeded = sizeof(QUERY_SERVICE_CONFIGW);
    LPQUERY_SERVICE_CONFIGW pConfig;

    do
    {
        buffer.resize(dwBytesNeeded);
        pConfig = (LPQUERY_SERVICE_CONFIGW) &buffer[0];

        if (QueryServiceConfigW(hService, pConfig, buffer.size(), &dwBytesNeeded))
            return pConfig->lpBinaryPathName;
    }
    while (GetLastError() == ERROR_INSUFFICIENT_BUFFER);

    return L"";
}