C ++阅读注册表使用服务失败但在控制台中成功相同

时间:2014-12-03 15:05:10

标签: c++ windows visual-studio-2010 visual-c++ service

程序启动后我必须立即阅读一些注册表值。如果代码是从命令提示符编译并运行的,那么代码可以正常工作并提供我寻求的注册表值。但是,如果我使用以下代码创建服务并将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 个答案:

答案 0 :(得分:1)

您正在查看HKCU,即当前用户的注册表配置单元。因此,您所描述的最合理的解释仅仅是该服务在不同的用户下运行。也就是说,该服务在交互式用户以外的用户帐户下运行。