考虑下图。
我编写了以下代码,该代码应该获取服务的路径路径,如图所示。基本上我在下面给出的代码片段将写在另一个生成 lpa.exe 的cpp文件中,并且应该作为服务运行。我尝试了 GetModuleFileName ,如果可执行文件(lpa.exe)正常运行(不作为服务),函数会找到正确的路径。但是一旦它作为服务运行,它就没有给出正确的路径并指向 system32 /...。为了解决这个问题,我相信以下代码片段可能就是解决方案:
#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;
}
代码编译但我得到异常在LearningCpp.exe中0x00ad1103处的未处理异常:0xC0000005:访问冲突读取位置0x0000000c。这意味着我遇到与指针有关的问题。我上面给出的代码有什么问题?
答案 0 :(得分:2)
QueryServiceConfig需要一个指向已分配内存的指针作为第二个参数。您指定大小,但指针为NULL,这会导致崩溃。
lpServiceConfig [out,optional]
指向接收服务配置信息的缓冲区的指针。数据的格式是QUERY_SERVICE_CONFIG结构。
此数组的最大大小为8K字节。要确定所需的大小,请为此参数指定NULL,为cbBufSize参数指定0。该函数将失败,GetLastError将返回ERROR_INSUFFICIENT_BUFFER。 pcbBytesNeeded参数将获得所需的大小。*
您必须为lpServiceConfig
参数分配内存。
这是一个官方的例子:
Querying a Service's Configuration
//
// 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);
}