问题描述
考虑下图。
我写了下面的代码,它应该获得服务的路径,如图所示。基本上,下面给出的代码片段将被写入另一个cpp文件,该文件将生成 lpa.exe ,并且应该作为服务运行。我尝试 GetModuleFileName 和函数找到正确的路径,如果可执行文件(lpa.exe)正常运行(不作为服务)。但是一旦它作为服务运行,它不给正确的路径和点指向 system32 /...。为了解决这个问题,我相信以下代码片段可能是解决方案:
I have written following code that is supposed to get the path to the executable of a service, highlighted in figure. Basically the code snippet I gave below will be written in the another cpp file that will generate the lpa.exe and is supposed to run as service. I tried GetModuleFileName and the function finds correct path if executable(lpa.exe) is run normally(not as service). But once it runs as service, it does not give correct path and points to system32/.... To solve the issue, I believe following snippet of code might be the solution:
#include <Windows.h>
#include <iostream>
int main()
{
SC_HANDLE sHandle;
LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
DWORD cbBufSize = 100;
LPDWORD bytesNeeded = NULL;
sHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
sHandle = OpenService(sHandle, "LogPointAgent",SERVICE_ALL_ACCESS);
QueryServiceConfig(sHandle,lpServiceConfig,cbBufSize,bytesNeeded);
std::cout << lpServiceConfig->lpBinaryPathName << std::endl;
}
代码编译但我得到异常未处理的异常在0x00ad1103在LearningCpp .exe:0xC0000005:访问冲突读取位置0x0000000c。这意味着我有与指针相关的问题。
The code compiles but I get exception Unhandled exception at 0x00ad1103 in LearningCpp.exe: 0xC0000005: Access violation reading location 0x0000000c. This means I am having issues related to pointer. What is wrong in code I gave above?
推荐答案
需要一个指向分配的内存的指针作为第二个参数,如果你指定一个大小第三个参数。
QueryServiceConfig requires a pointer that points to allocated memory as the second parameter if you specify a size with the third parameter. You specify the size, but the pointer is NULL, which causes the crash.
指向接收服务配置信息的缓冲区的指针。数据的格式为QUERY_SERVICE_CONFIG结构。
A pointer to a buffer that receives the service configuration information. The format of the data is a QUERY_SERVICE_CONFIG structure.
此数组的最大大小为8K字节。要确定所需的大小,请为此参数指定NULL,并为cbBufSize参数指定0。该函数将失败,GetLastError将返回ERROR_INSUFFICIENT_BUFFER。 pcbBytesNeeded参数将接收所需的大小。*
The maximum size of this array is 8K bytes. To determine the required size, specify NULL for this parameter and 0 for the cbBufSize parameter. The function will fail and GetLastError will return ERROR_INSUFFICIENT_BUFFER. The pcbBytesNeeded parameter will receive the required size.*
您必须为 lpServiceConfig
参数。
这是一个正式的例子:
//
// Purpose:
// Retrieves and displays the current service configuration.
//
// Parameters:
// None
//
// Return value:
// None
//
VOID __stdcall DoQuerySvc()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
LPQUERY_SERVICE_CONFIG lpsc;
LPSERVICE_DESCRIPTION lpsd;
DWORD dwBytesNeeded, cbBufSize, dwError;
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return;
}
// Get a handle to the service.
schService = OpenService(
schSCManager, // SCM database
szSvcName, // name of service
SERVICE_QUERY_CONFIG); // need query config access
if (schService == NULL)
{
printf("OpenService failed (%d)\n", GetLastError());
CloseServiceHandle(schSCManager);
return;
}
// Get the configuration information.
if( !QueryServiceConfig(
schService,
NULL,
0,
&dwBytesNeeded))
{
dwError = GetLastError();
if( ERROR_INSUFFICIENT_BUFFER == dwError )
{
cbBufSize = dwBytesNeeded;
lpsc = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, cbBufSize);
}
else
{
printf("QueryServiceConfig failed (%d)", dwError);
goto cleanup;
}
}
if( !QueryServiceConfig(
schService,
lpsc,
cbBufSize,
&dwBytesNeeded) )
{
printf("QueryServiceConfig failed (%d)", GetLastError());
goto cleanup;
}
if( !QueryServiceConfig2(
schService,
SERVICE_CONFIG_DESCRIPTION,
NULL,
0,
&dwBytesNeeded))
{
dwError = GetLastError();
if( ERROR_INSUFFICIENT_BUFFER == dwError )
{
cbBufSize = dwBytesNeeded;
lpsd = (LPSERVICE_DESCRIPTION) LocalAlloc(LMEM_FIXED, cbBufSize);
}
else
{
printf("QueryServiceConfig2 failed (%d)", dwError);
goto cleanup;
}
}
if (! QueryServiceConfig2(
schService,
SERVICE_CONFIG_DESCRIPTION,
(LPBYTE) lpsd,
cbBufSize,
&dwBytesNeeded) )
{
printf("QueryServiceConfig2 failed (%d)", GetLastError());
goto cleanup;
}
// Print the configuration information.
_tprintf(TEXT("%s configuration: \n"), szSvcName);
_tprintf(TEXT(" Type: 0x%x\n"), lpsc->dwServiceType);
_tprintf(TEXT(" Start Type: 0x%x\n"), lpsc->dwStartType);
_tprintf(TEXT(" Error Control: 0x%x\n"), lpsc->dwErrorControl);
_tprintf(TEXT(" Binary path: %s\n"), lpsc->lpBinaryPathName);
_tprintf(TEXT(" Account: %s\n"), lpsc->lpServiceStartName);
if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0)
_tprintf(TEXT(" Description: %s\n"), lpsd->lpDescription);
if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, TEXT("")) != 0)
_tprintf(TEXT(" Load order group: %s\n"), lpsc->lpLoadOrderGroup);
if (lpsc->dwTagId != 0)
_tprintf(TEXT(" Tag ID: %d\n"), lpsc->dwTagId);
if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)
_tprintf(TEXT(" Dependencies: %s\n"), lpsc->lpDependencies);
LocalFree(lpsc);
LocalFree(lpsd);
cleanup:
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
这篇关于获取可执行文件的服务路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!