草庐IT

CreateProcess() 似乎不受 lpCurrentDirectory 的影响

coder 2024-06-05 原文

我目前正在尝试使用 CreateProcess() API 启动一个进程: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

我遇到的主要问题是子进程似乎是在父进程的工作目录下启动的,不管 lpCurrentDirectory 参数中指示的是什么.

提供更多细节:lpCurrentDirectory 似乎适用于简单的命令行程序,但对于更复杂的程序(想想 GUI),它似乎没有被考虑在内,因为所有资源依赖项都是从调用目录进程中搜索的。

我可以尝试来回切换调用进程的工作目录,但第二个问题是被调用进程不在目标目录中。目前,它位于与调用进程相同的目录中,尽管将来可能会发生变化。当我试图调用与父进程位于不同目录中的子进程时,由于某种原因,它失败了。我已经多次检查目录结构,到目前为止没有结果。

我一直在四处寻找(包括 S.O.),虽然有些人似乎提示同样的问题,但我目前还没有找到可用的解决方法。请注意,例如,我不能改用 ShellExec,它必须是 CreateProcess()。

以防万一,我当前的测试系统是 Windows Seven 64 位。该软件应该可以在更广泛的操作系统上运行,从 XP 到 7、32 和 64 位(我猜 W8 目前不在范围内)。

[编辑] 我已经找到了在调用进程工作目录之外调用子进程的解决方案。我为此使用了 lpApplicationName,这很好,但显然不需要引用,即使是包含空格字符的复杂名称也是如此。

这让我可以测试修改调用进程的工作目录的想法(使用 SetCurrentDirectory() )调用 CreateProcess() 之前。令我惊讶的是,它不起作用:工作目录实际上是在 lpApplicationName 的完整路径中指定的目录,无论通过 SetCurrentDirectory() 为父工作目录设置了什么(并使用 GetCurrentDirectory() 验证)

这对我来说是个问题,因为我希望进程运行到另一个选定的目录(都在 lpCurrentDirectory 参数中指定,并在 CreateProcess() 之前调用 SetCurrentDirectory())。

最佳答案

我相信你的问题是你假设子进程应该尝试从当前目录加载它的资源(如你第三段中所建议的那样),而实际上一个进程从加载它的资源更为常见它从中启动的目录。换句话说,您所描述的行为在大多数情况下都符合预期。

当应用程序通过双击文档或使用拖放操作启动时,当前目录被设置为包含文档的目录,因此如果应用程序从当前目录加载资源,它会'工作。

这个简单的测试应用程序演示了 lpCurrentDirectory 的工作原理,因为子进程的当前目录设置为指定的目录:

#include <Windows.h>

void showcd(wchar_t * caption)
{
    wchar_t buffer[512];

    if (GetCurrentDirectory(512, buffer) == 0)
    {
        DWORD err = GetLastError();
        MessageBox(NULL, L"GetCurrentDirectory failed", caption, MB_OK);
        ExitProcess(err);
    }

    buffer[511] = L'\0';
    MessageBox(NULL, buffer, caption, MB_OK);
}

void parent(wchar_t * cd)
{
    wchar_t cmd[512];
    STARTUPINFO sinfo;
    PROCESS_INFORMATION pinfo;

    GetStartupInfo(&sinfo);

    showcd(L"Parent Process");

    if (GetModuleFileName(NULL, cmd, 512) == 0)
    {
        MessageBox(NULL, L"GetModuleFileName failed", L"Parent Process", MB_OK);
        ExitProcess(GetLastError());
    }

    cmd[511] = L'\0';

    if (!CreateProcess(
        cmd, NULL, NULL, NULL, FALSE, 0, NULL, cd, &sinfo, &pinfo
        ))
    {
        DWORD err = GetLastError();
        MessageBox(NULL, L"CreateProcess failed", L"Oops", MB_OK);
        ExitProcess(err);
    }
}

int CALLBACK WinMain( 
  _In_  HINSTANCE hInstance,
  _In_  HINSTANCE hPrevInstance,
  _In_  LPSTR lpCmdLine,
  _In_  int nCmdShow
) 
{
    wchar_t * cmdline;
    for (cmdline = GetCommandLine(); *cmdline; cmdline++)
    {
        if (*cmdline == L'*') 
        {
            parent(cmdline + 1);
            return 0;
        }
    }

    showcd(L"Child Process");
    return 0;
}

要测试应用程序,请使用如下命令行运行它:

currentdirectorytest *c:\Users\Public

来自父进程的第一个对话框显示了父进程的当前目录。第二个对话框来自子进程,显示子进程当前目录,应该是命令行中给出的目录。 (注意指定的目录必须存在,否则创建子进程会失败。)

关于CreateProcess() 似乎不受 lpCurrentDirectory 的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17395385/

有关CreateProcess() 似乎不受 lpCurrentDirectory 的影响的更多相关文章

  1. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  2. ruby-on-rails - 在 heroku 的 .fonts 文件夹中包含自定义字体,似乎无法识别它们 - 2

    Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在

  3. .net - .NET 将如何影响 Python 和 Ruby 应用程序? - 2

    我很好奇.NET将如何影响Python和Ruby应用程序。用IronPython/IronRuby编写的应用程序是否会非常特定于.NET环境,以至于它们实际上将变得特定于平台?如果他们不使用任何.NET功能,那么IronPython/IronRuby相对于非.NET同类产品的优势是什么? 最佳答案 我不能说任何关于IronRuby的东西,但是大多数Python实现(如IronPython、Jython和PyPy)都试图尽可能忠实于CPython实现。不过,IronPython正在迅速成为这方面的佼佼者之一,并且在PlanetPyth

  4. ruby-on-rails - "rails generate rspec:install"似乎失败了 - 2

    运行:ruby1.9.3p0和Rails3.2.1尝试使用rspec但当我尝试将其安装到我的应用程序中时出现以下错误:/Users/Si/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.1/lib/rails/railtie/configuration.rb:85:in`method_missing':undefinedmethod`generators'for#(NoMethodError)from/Users/Si/.rvm/gems/ruby-1.9.3-p0/gems/rspec-rails-2.0.0.beta.18/lib/rspec-r

  5. ruby-on-rails - Heroku Action 缓存似乎不起作用 - 2

    我一直在Heroku上尝试不同的缓存策略,并添加了他们的memcached附加组件,目的是为我的应用程序添加Action缓存。但是,当我在我当前的应用程序上查看Rails.cache.stats时(安装了memcached并使用dalligem),在执行应该缓存的操作后,我得到current和total_items为0。在Controller的顶部,我想缓存我有的Action:caches_action:show此外,我修改了我的环境配置(对于在Heroku上运行的配置)config.cache_store=:dalli_store我是否可以查看其他一些统计数据,看看它是否有效或我做错

  6. 未来的趋势————以ChatGPT为标杆的AI对生活的影响是巨大的 - 2

    文章目录前言1.AI的发展历程2.我是如何接触到人工智能的概念和产品的3.对于ChatGPT的一点看法4.AI对大学毕业生的职业发展的利与弊5.对于AI的思考和问题前言随着ChatGPT的爆火,生成式AI,大模型的人工智能被越来越多的人注意到,同时他也带来了许多问题。本文将对几方面进行探讨。1.AI的发展历程远古时期在公元前第一个千禧年,中国,印度和希腊哲学家都提出了一些推理的研究理论,比如亚里士多德(Aristotle)进行了演绎推理三段论的完整分析,欧几里得(Euclid)所著Elements是一种形式推理的模型,MuḥammadibnMūsāal-Khwārizmī,发明了代数学,即我们

  7. ruby - Ruby 中的正则表达式负后视似乎不起作用 - 2

    制作参数解析器。我想将一个字符串拆分为一个分隔符为","的数组除非前面有"|".这意味着字符串"foo,ba|,r,arg"应该导致`["foo","ba|,r","arg"]`我正在尝试使用这个正则表达式:(?适用于http://regexhero.net/tester/但是当我尝试args.split(/(?在ruby​​中,我得到一个错误:undefined(?...)sequence:/(? 最佳答案 Ruby的正则表达式引擎还不支持lookbehind。您需要切换到1.9或使用Oniguruma.如果这不是一个选项,您可以

  8. ruby - 为什么 Ruby 似乎随机访问目录中的文件? - 2

    这是设计使然吗?代码如下:classFileRenamerdefRenameFiles(folder_path)files=Dir.glob(folder_path+"/*")endendputs"Renamingfiles..."renamer=FileRenamer.new()files=renamer.RenameFiles("/home/papuccino1/Desktop/Test")putsfilesputs"Renamingcomplete."获取文件的顺序似乎是随机的,而不是它们在Nautilus中显示的那样。这是设计使然吗?我只是好奇。 最

  9. ruby-on-rails - Ruby on Rails 似乎是由 link_to 创建的自动转义 html - 2

    这是我的代码,我试图用.to_sentence以句子形式显示指向bboy的工作人员的链接列表0)%>1)then"Crew".pluralizeelse"Crew"end%>:Independent我得到的输出是正确的链接,但它显示为:HustleKidzandKnuckleheadsCali而不是:HustleKidzandKnuckleheadsCali转义了html,而不是所需的链接。我错过了什么吗?我试过CGI.unescapeHTML和其他几个,但我迷路了...... 最佳答案 Rails3现在自动转义一切,为了输出原始H

  10. ruby-on-rails - Simplecov 覆盖率报告似乎遗漏了某些行 - 2

    在澄清了simplecov如何确定一条线是否已被测试执行之后。我有以下方法:defover?end_at其中end_at是对象的ActiveRecord属性。在以下规范中进行了练习:describeCalendarEntrydoit'candeterminethataneventhasended'do@entry.end_at=1.day.ago@entry.over?.shouldbe_trueendend在覆盖范围内运行规范后,它显示以下结果:我已经在Debug模式下运行了测试,并在此行上设置了一个断点,并确认规范确实符合它。这并不仅限于此方法中的这一行,包括使用ActiveRec

随机推荐