【问题标题】:Launching 64bit process from 32bit program从 32 位程序启动 64 位进程
【发布时间】:2013-03-11 06:10:29
【问题描述】:

我有一个 32 位程序,我试图在 64 位计算机上运行。我正在运行 vssadmin 命令来获取还原点信息并将其保存到文本文件中。 现在,它在我的 32 位计算机上运行良好,我在我朋友的 64 位计算机上测试它,但它不工作。

如果我在 64 位系统上运行的 32 位应用程序中使用 system(),它会使用 32 位命令提示符吗?这是我能想到的唯一会阻止它工作的事情,因为我已经从命令提示符手动运行命令并且它工作正常。

如果是这样呢?有没有强制它使用正确的命令提示符?

【问题讨论】:

  • 永远不要使用 system(),使用 CreateProcess()
  • @JonathanD Rightio,我正在改用 createprocess(),但在将字符串转换为 LPWSTR 时遇到问题。我找到了一些应该这样做的代码,但事实并非如此。现在我正在尝试std::wstring widestr = std::wstring(vsscommand.begin(), vsscommand.end()); wchar_t* widecstr = widestr.c_str();,但我得到了Error 2 error C2440: 'initializing' : cannot convert from 'const wchar_t *' to 'wchar_t *'
  • 你不必将 std::wstring 转换为 wchar。您得到的错误是因为您将常量转换为非常量,这是不可能的,因为它是常量:D

标签: c++ 64-bit system 32-bit


【解决方案1】:

在 Linux 和 Windows [我也相信 BSD/MacOS] 中,32 位应用程序可以使用相关的“创建新进程”系统调用来启动 64 位进程 [system() 向下做了几层在它启动的外壳内]。

唯一的限制是 32 位可执行文件不能使用 64 位共享库(.so 或 .dll),反之亦然。但是一个新进程首先加载一个新的可执行文件,此时该进程可以是 32 位或 64 位,具体取决于可执行文件本身。

【讨论】:

  • 即使 32 位进程试图启动 64 位进程来调试它(在 Windows 上),这是否是真的?当从 32 位调用以使用 DEBUG_ONLY_THIS_PROCESS 启动 64 位进程时,似乎 CreateProcessW 失败(“不支持请求”)。反之亦然。
  • @AdrianMcCarthy:不能这么说,因为在过去的 5-6 年里,除了阅读电子邮件之外,我还没有编程/使用过 Windows,也从未尝试过那种特别的东西(我所有的机器都运行 Linux在家里和工作中——在工作中我有一个用于访问邮件的虚拟机),但是不能从 32 位进程中调试 64 位进程并不是不合理的——它至少需要 API 来进行一般调试进行重大更改以支持所有相关的寄存器信息和进程状态 - “读取进程内存”和“写入进程内存”也必须支持 64 位地址。
【解决方案2】:

您应该始终避免使用 system(),因为

  • 资源繁重
  • 它破坏了安全性——你不知道它是否是一个有效的命令或者在每个系统上都做同样的事情(参见 Mats Petersson 的回答),你甚至可以启动你不打算启动的程序。 危险在于,当您直接执行程序时,它会获得与您的程序相同的权限——这意味着,例如,如果您以系统管理员身份运行,那么您刚刚无意中执行的恶意程序也会以系统管理员身份运行行政人员。如果这不会吓到您,请检查您的脉搏。
  • 反病毒程序讨厌它,您的程序可能会被标记为病毒。

你应该使用CreateProcess()。

您可以使用 Createprocess() 来启动一个 .exe 并为其创建一个新进程。 该应用程序将独立于调用应用程序运行。

这是我在一个项目中使用的示例:

VOID startup(LPCTSTR lpApplicationName)
{
   // additional information
   STARTUPINFO si;     
   PROCESS_INFORMATION pi;

   // set the size of the structures
   ZeroMemory( &si, sizeof(si) );
   si.cb = sizeof(si);
   ZeroMemory( &pi, sizeof(pi) );

  // start the program up
  CreateProcess( lpApplicationName,   // the path
    argv[1],        // Command line
    NULL,           // Process handle not inheritable
    NULL,           // Thread handle not inheritable
    FALSE,          // Set handle inheritance to FALSE
    0,              // No creation flags
    NULL,           // Use parent's environment block
    NULL,           // Use parent's starting directory 
    &si,            // Pointer to STARTUPINFO structure
    &pi )           // Pointer to PROCESS_INFORMATION structure
    ) 
    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
}

注意:正如我之前所说,system() 在不同的机器上不会做同样的事情,Mats Petersson 解释了原因

【讨论】:

  • 干杯伙伴。我会再调查一下。绝对看起来比使用 system() 更好,考虑到它对我来说已经是行为不端了。
  • 它回答了我的问题吗?我的问题是如何从 32 位进程运行 64 位进程,而不是“我为什么不应该使用 system()?”
  • 您是否尝试过使用我的代码运行 64 位进程?正如我所说,system() 在每个系统上的工作方式都不一样。
  • 我不能被这个 createprocess() 所困扰,这很麻烦,而且不值得为我需要它而烦恼。厌倦了转换字符串和 wstrings 以及 LCPSTR 和 LCPWSTR 以及所有其他该死的东西。我需要调用 C:\\Windows\\System32\\cmd.exe 而不是让它默认,因为它无疑会在 64 位系统上从 32 位应用程序运行时使用 32 位。然后我有一个 std::string 需要传递,但将其转换为它甚至可以理解的东西太麻烦了
  • 如果你觉得 createprocess() 很难,你应该阅读更多的 C++ 书籍
猜你喜欢
  • 1970-01-01
  • 2012-01-19
  • 2011-01-01
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
  • 2010-09-14
  • 2018-07-30
  • 1970-01-01
相关资源
最近更新 更多