如何通过在本地配置文件下运行服务从Windows服务获取用户appdata路径

时间:2014-02-08 12:46:53

标签: winforms winapi visual-c++ service app-data

我编写了一个Windows服务,允许我使用CreateProcessASUser()执行application.exe。

HANDLE hTokenDup = NULL;
DuplicateTokenEx(auToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
CreateProcessAsUserW(hTokenDup, NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

这是我的申请来源:

    static bool first = true;

    TCHAR* getAppDataFolder() {
        TCHAR* pathTchar = (TCHAR*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (_MAX_PATH + 1) * sizeof(TCHAR));
        BOOL getAppdata = SHGetSpecialFolderPath(0, pathTchar, CSIDL_APPDATA, false );


        return pathTchar;
    }

    BOOL WriteFileFromWCHAR(HANDLE hFile, 
LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
 LPDWORD lpNumberOfBytesWritten)
    {
        BYTE* arr = new BYTE[nNumberOfBytesToWrite];
        TCHAR* buff = (TCHAR*)lpBuffer;
        for(int i = 0; i < nNumberOfBytesToWrite; i++) {
            arr[i] = (BYTE)buff[i];
        }
        return WriteFile( hFile , arr , nNumberOfBytesToWrite , lpNumberOfBytesWritten, NULL);
    }

    int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show)
    {
        int argc = 0;
        _TCHAR** argv;

        LPTSTR cmdLine = GetCommandLine();
        argv = CommandLineToArgvW(cmdLine, &argc );



        if(argc == 2) {

            TCHAR* path = getAppDataFolder();


            HANDLE hFile = CreateFile( argv[1] , GENERIC_WRITE , 0 , NULL  , CREATE_ALWAYS , 0 , 0 );
            if ( hFile != INVALID_HANDLE_VALUE )
            {

                DWORD lpNumberOfBytesWritten;

                WriteFileFromWCHAR(hFile, path, lstrlen(path), &lpNumberOfBytesWritten);
            }
            else {

            }




        }
        return 0;
    }

我需要在文件中写下这个地址(例如:“C:\ Users \ CurrentUser \ AppData \ Roaming”)。但是,当我从Windows服务检索appdata路径时,我得到以下路径“C:\ Windows \ system32 \ config \ systemprofile \ AppData \ Roming”。如何在C ++中编写代码以允许我的服务执行应用程序并在文件中写入预期的路径?

1 个答案:

答案 0 :(得分:1)

在使用任何依赖于用户特定设置的API之前,您必须模拟用户(您已拥有用户的令牌)。此外,您需要在致电LoadUserProfile()之前致电CreateProcessAsUser()(使用相同的令牌)。