【问题标题】:Use SHGetKnownFolderPath in path of CreateProcess to run program在 CreateProcess 的路径中使用 SHGetKnownFolderPath 来运行程序
【发布时间】:2019-08-21 10:23:30
【问题描述】:

我正在尝试使用函数 SHGetKnownFolderPath() 来获取用户的 localappdata 目录并将 PWSTR(它是 wchar_t*)转换为 LPCSTR(它是 const char*),然后将程序添加到 LPCSTR以便它可以在 CreateProcess 中使用。

我想出了如何使用 SHGetKnownFolderPath 并使用 printf(%ls%, path) 将路径打印到控制台,并想出了如何使用 CreateProcess 执行 .exe 文件,但我不知道如何将 PWSTR 变成一个 const char* 并将我要执行的程序包含在该 const char* 中。

#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, &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, &info, &processInfo);
.......................
    }

我不会说我对编码了解很多,而且可能有一些重要的事情我还不知道。任何帮助将不胜感激。

编辑

我认为如果我展示我的代码的其他部分会更有帮助。下面的代码就在我上面写的代码之后:

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

【问题讨论】:

  • 使用 wchar_t 比执行任何转换要容易得多。您可以通过在其前面加上 L 来获得一个宽字符串文字,如 L"my_program.exe"。然后,您可以使用 swprintf 而不是 sprintf 将 SHGetKnownFolderPath 的结果与文字结合起来,或者将 std::wstring 用于相同目的,然后将完整的可执行路径提供给 CreateProcess。
  • @SornelHaetir "然后将完整的可执行路径提供给 CreateProcess" - 你的意思是 CreateProcessW()。 OP 需要转换为 char 的事实意味着该项目未配置为 Unicode,因此 CreateProcess() 映射到 CreateProcessA()

标签: c++ char type-conversion constants wchar-t


【解决方案1】:

根本不要转换为charSHGetKnownFolderPath() 返回一个 Unicode 字符串。显式使用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, &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(&execute[0], NULL, NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo);
        // ...
    }
    return 0;
}

【讨论】:

  • 我收到一个新错误 (C2664):无法将参数 1 从“int”转换为“LPCWSTR”。当我在CreateProcessW(NULL &amp;execute[0]... 中有NULL 时会发生此错误我将如何解决这个问题?提前致谢。
  • @WolfZwiener 当然,您应该能够弄清楚CreateProcessW(NULL &amp;execute[0]... 有什么问题? CreateProcessW 的第一个参数是一个指向 Unicode 字符串的指针,那么如何解决这个问题,使它成为一个指向 Unicode 字符串的指针呢? (这只是一个印刷错误。)
  • @RaymondChen 哦,是的,你是对的,我让程序现在可以运行了。非常感谢!
猜你喜欢
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2010-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多