【问题标题】:CReateProcess() API causing Unhandled exception. C++ std:: alternative API for CreateProcessCReateProcess() API 导致未处理的异常。 C++ std:: CreateProcess 的替代 API
【发布时间】:2014-08-14 06:12:01
【问题描述】:

我有一个 Vc++ 代码、一个 A.EXE 项目 (MBCS) 和一个静态库项目 (Unicode)。静态库 (*.lib) 项目具有如下代码,它尝试从其中启动不同的 exe(例如 pwrtest.exe)。但是当执行 CReateProcess() 语句时,代码会崩溃。

错误是“A.EXE”中 (ntdll.dll) 处的未处理接收: ::Access Vioaltion读取位置0xCCCCCCCC

我确保 appPath 和 workdir 中的值是正确的。 它们是这样的值:: c:\Users\abcd\xyz\somedirectory\abc 等... 目录名称用双斜杠“\”分隔。

我真的不明白这是什么问题。

我还添加了一个 try catch 语句,但是当我在 CreateProcess() 行上进入代码 (F10) 时,它会立即崩溃并抛出上述异常。 所以它甚至没有来 catch 声明。

由于 Create process() 是一个 C API 和 C 类型总是容易出现内存 elaks 等,只是想知道是否有一个 C++ STD:: 库对应物(一些容器函数 API),它更简单但是做 CreateProcess() C API 的工作。

 PROCESS_INFORMATION pI;
    STARTUPINFO         sI;
    LPTSTR              appPath;
    LPTSTR              workDir;

    wchar_t cwd[_MAX_PATH];
    GetCurrentDirectory(_MAX_PATH, cwd);
    wchar_t TestEXEPath[_MAX_PATH];
    wcscpy(TestEXEPath, cwd);

    wcscat(TestEXEPath, L"\\somedircetory\\abc\\pwrtest.exe /sleep /c:1");

    appPath = TestEXEPath;
    wchar_t workDirForTestEXE[_MAX_PATH];
    wcscpy(workDirForTestEXE, cwd);
    wcscat(workDirForTestEXE, L"\\somedirectory\\abc");
    workDir = workDirForTestEXE;

    try
    {
        if (!CreateProcess(NULL, appPath, NULL, NULL, FALSE, 0, NULL, workDir, &sI, &pI))
        {
            ......
        }
        {
            ......
        }
    }
    catch (exception& exType)
    {
        std::cout << "ExType is" << exType.what() << endl;
    }

【问题讨论】:

    标签: c++ exception visual-c++ exception-handling createprocess


    【解决方案1】:

    您的变量sI 未初始化,它是一个输入参数。当CreateProcess 从中读取时,可能会发生各种不好的事情。一些成员被定义为指向字符串的指针。从无效指针读取不是 C++ 异常,这就是您的 catch 语句没有处理它的原因。

    修复很简单,改一下

    STARTUPINFO sI;
    

    STARTUPINFO sI = {sizeof sI};
    

    标准 C++ 库中没有任何函数能像操作系统特定的 CreateProcess 一样强大。您正在使用CreateProcess 的能力来控制初始工作目录,这是systemspawnexec 无法做到的。 (fork + cwd + exec 可以,但这是在 Windows 上做事的一种非常糟糕的方式)

    【讨论】:

    • 谢谢。它修复了崩溃问题。但只是想知道这个语句“STARTUPINFO sI = {sizeof sI};”。 STARTUPINFO 是一个结构。通过做{sizeof si},我们这里如何初始化结构对象?
    • @codeLover:结构中的第一项,cbSize,设置为sizeof sI。其余设置为零。 “如果列表中的初始值设定项少于结构的成员,则尾随成员初始化为 0。”
    • 谢谢。因此,由于此结构中的第一个成员是结构的大小,因此该语句“{sizeof } 工作正常。所以为了初始化任何此类结构,常用方法应该是用它的第一个成员的值来初始化它权利? 所以其余的将被初始化为“0”。(假设我们对使用某些特定值初始化它的成员不感兴趣。只是想知道,如果我们在这里将结构变量 sI 初始化为全“0”,那么什么这是作为输入参数传递的原因吗?
    • @codeLover: 这个结构提供了很多选项?想要最小化启动程序?在这里做。想要将输出重定向到文件?在这里做。 STARTUPINFO 的 MSDN 文档解释了您可以控制的所有内容以及需要设置哪些结构变量和标志才能激活它们。
    猜你喜欢
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多