Как получить путь к appdata пользователя из службы Windows, запустив службу под локальным профилем
Я написал службу Windows, которая позволяет мне выполнять application.exe с помощью CreateProcessASUser()
,
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") в файле. Но когда я получаю путь appdata из службы Windows, я получаю следующий путь "C:\Windows\system32\config\systemprofile\AppData\Roming" . Как мне написать код на C++, чтобы мой сервис мог выполнить приложение и записать ожидаемый путь в файл?
1 ответ
Вы должны выдать себя за пользователя (у вас уже есть токен пользователя) перед использованием любых API, которые зависят от пользовательских настроек. Также вам нужно позвонить LoadUserProfile()
(используя тот же токен) перед вызовом CreateProcessAsUser()
,