C++读取注册表时使用服务失败但在控制台中同样成功
Posted
技术标签:
【中文标题】C++读取注册表时使用服务失败但在控制台中同样成功【英文标题】:C++ Reading Registry When using Service fails but the same succeds in Console 【发布时间】:2014-12-03 15:05:10 【问题描述】:程序一启动,我就必须读取一些注册表值。如果代码是从命令提示符编译和运行的,则代码确实可以正常工作并提供我寻求的注册表值。但如果我创建服务并使用以下代码将 exe 附加到服务:
sc create someservice start=auto binpath= "PATH to EXE of Code"
并运行服务我没有得到想要的值。我附上了完整的代码。我也记录了每一步的结果。
#include <Windows.h>
#include <iostream>
#include <string>
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
int WriteToLog(const char *);
std::string GetLPInstalledPath();
std::string GetLPInstalledPath()
HKEY hKey;
char buf[255];
DWORD dwType;
DWORD dwBufSize = sizeof(buf);
std::string ss="";
const char* subkey = "Software\\\\Logpoint\\\\InstalledPath";
WriteToLog(" Inside GetLPInstalledPath") ;
if( RegOpenKey(HKEY_CURRENT_USER,subkey,&hKey) == ERROR_SUCCESS)
WriteToLog("Opened the Registry Key");
dwType = REG_SZ;
if( RegQueryValueEx(hKey,"path",0, &dwType, (BYTE*)buf, &dwBufSize) == ERROR_SUCCESS)
ss = buf;
WriteToLog(ss.c_str());
else
WriteToLog(" Cound not find the value");
RegCloseKey(hKey);
else
WriteToLog(" Cannot Open the Installed Registry Path");
return ss;
int WriteToLog(const char* str)
//const char *logfile = "D:\\ubuntu_share\\lpa\\lpa_c\\build_win\\src\\lpa\\sample.txt";
FILE* log;
log = fopen("C:\\lpa\\sample.txt", "a+");
if (log == NULL)
return -1;
fprintf(log, "%s\n", str);
fclose(log);
return 0;
int Run()
WriteToLog("Run");
WriteToLog("entering infinite loop of main thread ");
while(1);
WriteToLog("end of main thread ");
return 0;
void ControlHandler(DWORD request)
//LOG4CPLUS_INFO(root, "ControlHandler: Entry";
switch(request)
case SERVICE_CONTROL_STOP:
//WriteToLog("Monitoring stopped.");
WriteToLog( "ControlHandler: SERVICE_CONTROL_STOP Request");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
if(SetServiceStatus (hStatus, &ServiceStatus)==FALSE)
WriteToLog("ServiceCtrlHandler: SetServiceStatus returned error");
return;
case SERVICE_CONTROL_SHUTDOWN:
// WriteToLog("Monitoring shutdown.");
WriteToLog("ControlHandler: SERVICE_CONTROL_SHUTDOWN Request");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
if(SetServiceStatus (hStatus, &ServiceStatus) == FALSE)
WriteToLog("ServiceCtrlHandler: SetServiceStatus returned error");
return;
case SERVICE_CONTROL_INTERROGATE:
return;
default:
WriteToLog("ServiceCtrlHandler");
break;
// Report current status
SetServiceStatus (hStatus, &ServiceStatus);
WriteToLog("ServiceCtrlHandler: Exit");
return;
void ServiceMain(int argc, char** argv)
//WriteToLog("at ServiceMain");
WriteToLog("ServiceMain");
int error;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(
"MemoryStatus",
(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == NULL)
// Registering Control Handler failed
WriteToLog("ServiceMain: RegisterServiceCtrlHandler returned error");
return;
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
if(SetServiceStatus (hStatus, &ServiceStatus)==FALSE)
WriteToLog("ServiceMain: SetServiceStatus returned error");
WriteToLog("ServiceMain: Performing Service Start Operations");
Run();
WriteToLog("ServiceMain: Performing Cleanup Operations");
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 3;
if (SetServiceStatus (hStatus, &ServiceStatus) == FALSE)
WriteToLog("ServiceMain: SetServiceStatus returned error");
WriteToLog("ServiceMain: Exit");
return;
int StartLpaService()
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "MemoryStatus";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
if(StartServiceCtrlDispatcher(ServiceTable) == FALSE)
WriteToLog("StartLpaService: StartServiceCtrlDispatcher returned error");
return GetLastError ();
WriteToLog("Main: Exit");
return 0;
int main(int argc, char **argv)
std::string pa = GetLPInstalledPath();
#ifdef SERVICE_DEBUG
WriteToLog("SERVICE_DEBUG");
Sleep(15000);
#endif
StartLpaService();
return 0;
我面临的问题是,如果程序的服务启动,没有写入注册表值,而是直接从命令提示符运行给出值。我该如何解决这个问题?
【问题讨论】:
【参考方案1】:您正在查看HKCU
,即当前用户的注册表配置单元。因此,对于您所描述的内容,最合理的解释只是该服务在不同的用户下运行。即服务在交互式用户以外的用户帐户下运行。
【讨论】:
我如何知道在哪个用户帐户下运行服务?那么我应该写HKCU以外的值吗? @SarvagyaPant:您在创建服务时配置用户。通常的解决方案是HKLM
。
嗯,这取决于我认为的问题。您可以尝试从 HKLM 阅读,但大概您从 HKCU 阅读,因为那是您想要的信息所在的地方。所以,问问自己,你想阅读的信息在哪里?
也是默认方式服务被创建为LocalSystem。这是否意味着我必须使用 HKLM?
你必须记住,我们不知道这个注册表项是什么,你为什么期望它存在,你会用它做什么等等。请记住,我们只是回答提出的问题。你问为什么服务看不到密钥。我试图回答这个问题。现在,如果所有相关方都使用 HKLM,那么密钥将被共享。模 32/64 位注册表重定向。你几乎肯定不希望你的服务是LocalSystem
。这是不好的做法。以上是关于C++读取注册表时使用服务失败但在控制台中同样成功的主要内容,如果未能解决你的问题,请参考以下文章
DirectX9 CreateDevice 在 C 中失败,但在 C++ 中成功
windows services 读取注册表配置文件一般在哪个目录