SHGetFolderPath返回本地路径但不同时运行为服务

时间:2014-12-08 07:30:23

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

我有以下代码在System 32文件夹中提供Local App Data文件夹。我附上了以下代码:

int WriteToLog(const char* str)
{
    FILE* log;
    log = fopen("C:\\lpa\\sample.txt", "a+");
    if (log == NULL)
        return -1;
    fprintf(log, "%s\n", str);
    fclose(log);
    return 0;
}
std::string GetLocalAppDataPath()
{
    HANDLE hfile;
    TCHAR szPath[MAX_PATH];
    if(SUCCEEDED(SHGetFolderPath(NULL,CSIDL_LOCAL_APPDATA,NULL,0, szPath))) 
    {
        std::string path = boost::lexical_cast<std::string>(szPath);
        boost::replace_all(path, "\\", "\\\\");
        return path;
    }
}

void LoggingInit()
{
        log4cplus::initialize ();
        helpers::LogLog::getLogLog()->setInternalDebugging(false);
        std::string app_data_path = GetLocalAppDataPath();
        std::string log_folder_path = app_data_path + "\\\\lpa\\\\output\\\\";
        std::string log_file = log_folder_path + "output.log";
        WriteToLog(log_file.c_str());
        SharedAppenderPtr append_1(new RollingFileAppender(LOG4CPLUS_TEXT(log_file), 10*1024*1024, 5));
        append_1->setName(LOG4CPLUS_TEXT("LogpointAgentLog"));
        PatternLayout *p = new PatternLayout(LOG4CPLUS_TEXT("[%D] <%-5p> [%F : %L] %m%n"));
        append_1->setLayout(std::auto_ptr<Layout>(p));
        Logger::getRoot().addAppender(append_1);
        root = Logger::getRoot();
        WriteToLog("Loging Init Successful");
        //std::string path = GetRegistryPath();
        //WriteToLog(path.c_str());
}

当我使用制作服务创建运行程序时,我没有获得真正的本地应用程序数据路径。

int main(int argc, char **argv)
{ 
    WriteToLog("Logging Init");
    LoggingInit();
    LOG4CPLUS_INFO(root,  "Running as service");
    StartLpaService(); //Here I am creating a service.
    return 0;
}

我在 WriteToLog 功能

创建的文本文件中获得以下数据
Logging Init
C:\\WINDOWS\\system32\\config\\systemprofile\\AppData\\Local\\lpa\\output\\output.log
Loging Init Successful

如果可执行文件作为“正常”而不是“服务”运行,我将获得本地应用程序数据路径。

C:\\Users\\logpoint\\AppData\\Local\\

代码有什么问题?

1 个答案:

答案 0 :(得分:0)

感谢Igor提供的见解。我在制作wix安装程序时在Registry中编写 LocalAppDataFolder 路径解决了这个问题。为此我用过:

<Component Id="registry_values" Guid="{11FB6C4C-3C90-4F46-B0D2-BB95150F60E6}">
        <RegistryKey Root="HKLM"
                     Key="Software\Logpoint"
              Action="createAndRemoveOnUninstall">
          <RegistryValue Type="string" Name="path" Value="[LocalAppDataFolder]"/>
        </RegistryKey>
</Component>

由于写入的注册表路径因64位和32位窗口而异,所以我按照以下代码了解它:

bool DetectWindowsVersionBit()
{
#if defined( WIN64 )
  return true; // 64-bit process running on 64-bit windows
#endif

  BOOL bIsWow64 = false; // must default to FALSE
  typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
  LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
    GetModuleHandle("kernel32"), "IsWow64Process");

  if (NULL != fnIsWow64Process)
  {
    if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
    {
      //ASSERT( FALSE ); // something went majorly wrong
    }
  }
  return bIsWow64;
}

因此,我创建了自己的代码来访问路径。我现在没有使用 SHGetFolderPath 。这是:

std::string GetLocalAppDataPath()
    {
        HKEY hKey;
        char buf[255];
        DWORD dwType;
        DWORD dwBufSize = sizeof(buf);
        std::string ss="";
        const char *subKey;
        bool is64bit =  DetectWindowsVersionBit();
        if(is64bit)
        {
            subKey = "Software\\\\Wow6432Node\\\\Logpoint";
        }
        else
        {
            subKey = "Software\\\\Logpoint";
        }
        WriteToLog(" Inside GetLocalAppDataPath") ;
        if( RegOpenKey(HKEY_LOCAL_MACHINE,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 Local App Data Path");

        }

        return ss;
    }