Используйте SHGetKnownFolderPath в пути к CreateProcess для запуска программы

#c #char #type-conversion #constants #wchar-t

#c #символ #преобразование типов #константы #wchar-t

Вопрос:

Я пытаюсь использовать функцию SHGetKnownFolderPath(), которая получает каталог localappdata пользователя и преобразует PWSTR (который является wchar_t *) в LPCSTR (который является постоянным символом *), затем добавьте программу в LPCSTR, чтобы ее можно было использовать в CreateProcess.

Я понял, как использовать SHGetKnownFolderPath и вывести путь к консоли с помощью printf (%ls%, path) и выяснил, как использовать CreateProcess для выполнения exe-файла, но я не знаю, как преобразовать PWSTR в постоянный символ * и включить программу, которую я хочу выполнить, в этот постоянный символ *.

 #include <Windows.h>
#include <fstream>
#include <shlobj_core.h>
#include <string>
#include <KnownFolders.h>
#include <wchar.h>

int main () {
    //SHGetKnownFolderPath function
    PWSTR path = NULL;
    HRESULT path_here = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, amp;path);

    //CreateProcess funtion
    STARTUPINFO info = { sizeof(info) };
    PROCESS_INFORMATION processInfo;
    const char* execute = //Want to have path_here plus another folder and an .exe program.
    BOOL create = CreateProcess(execute, NULL, NULL, NULL, FALSE, 0, NULL, NULL, amp;info, amp;processInfo);
.......................
    }
  

Я бы не сказал, что я много знаю о кодировании, и, вероятно, есть что-то важное, о чем я еще не знаю. Буду признателен за любую помощь.

Редактировать

Я думаю, было бы более полезно, если бы я показал эту другую часть моего кода. Следующий код находится сразу после кода, который я написал выше:

 if (create){
    WaitForSingleObject(processInfo.hProcess, INFINITE);
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
 }
  

Комментарии:

1. Это было бы намного проще, используя wchar_t повсюду, а не выполняя какое-либо преобразование. Вы можете создать строковый литерал с широкими символами, добавив к нему префикс L, как в L»my_program.exe «. Затем вы можете использовать swprintf вместо sprintf, чтобы объединить результаты SHGetKnownFolderPath с литералом, или использовать std::wstring для той же цели, а затем передать полный путь к исполняемому файлу в CreateProcess.

2. @SoronelHaetir » затем введите полный путь к исполняемому файлу в CreateProcess » — вы имеете в виду CreateProcessW() . Тот факт, что OP необходимо преобразовать в char означает, что проект не настроен для Unicode и, следовательно, CreateProcess() сопоставляется с CreateProcessA() .

Ответ №1:

Вообще не преобразовывайте в char . SHGetKnownFolderPath() возвращает строку в Юникоде. Используйте CreateProcessW() явно, чтобы вы могли передать ему строку Unicode:

 #include <Windows.h>
#include <fstream>
#include <shlobj_core.h>
#include <string>
#include <KnownFolders.h>
#include <wchar.h>

int main ()
{
    PWSTR path = NULL;
    HRESULT hres = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, amp;path);
    if (SUCCEEDED(hres))
    {
        STARTUPINFOW info = { sizeof(STARTUPINFOW) };
        PROCESS_INFORMATION processInfo;
        std::wstring execute = std::wstring(path)   L"\folder\program.exe";
        CoTaskMemFree(path);
        BOOL create = CreateProcessW(amp;execute[0], NULL, NULL, NULL, FALSE, 0, NULL, NULL, amp;info, amp;processInfo);
        // ...
    }
    return 0;
}
  

Комментарии:

1. Я получил новую ошибку (C2664): не удается преобразовать аргумент 1 из ‘int’ в ‘LPCWSTR’. Эта ошибка возникает, когда у меня есть NULL в CreateProcessW(NULL amp;execute[0]... Как бы мне это решить? Заранее спасибо.

2. @WolfZwiener Конечно, вы должны быть в состоянии выяснить, что не так с CreateProcessW(NULL amp;execute[0]... ? Первый параметр CreateProcessW — это указатель на строку Unicode, так как же это исправить, чтобы это был указатель на строку Unicode? (Это просто опечатка.)

3. @RaymondChen О, да, ты прав, теперь я заставил программу работать. Большое спасибо!