C++ CreateProcess失败-错误183

C++ CreateProcess失败-错误183,c++,windows,createprocess,C++,Windows,Createprocess,所以,我无法更改的代码调用可执行文件,我需要给它不同于黑盒代码调用的命令行参数。我想我可以制作一个可执行文件作为代理proc.exe位于黑盒部分所需的位置,获取命令行参数,修改它们,然后调用原始文件procReal.exe 不幸的是,CreateProcess似乎无法启动,返回状态183。我已经查了所有我能查到的东西,但找不到太多。我尝试过翻转,将句柄继承设置为true,手动指定工作目录,而不做这两件事。不走运。我假设在继承调用应用程序的适当安全上下文时出现了一些问题,因此包装器可以作为适当的传

所以,我无法更改的代码调用可执行文件,我需要给它不同于黑盒代码调用的命令行参数。我想我可以制作一个可执行文件作为代理
proc.exe
位于黑盒部分所需的位置,获取命令行参数,修改它们,然后调用原始文件
procReal.exe

不幸的是,CreateProcess似乎无法启动,返回状态183。我已经查了所有我能查到的东西,但找不到太多。我尝试过翻转,将句柄继承设置为true,手动指定工作目录,而不做这两件事。不走运。我假设在继承调用应用程序的适当安全上下文时出现了一些问题,因此包装器可以作为适当的传递来工作,但我不知道如何做

下面的代码,删除了不相关的部分

编辑在请求后将完整代码放在此处。这已经没有任何意义了。现在它将部分工作,但仅当
traceFile
fopen
部分不存在时。甚至连fprintfs都没有移除,特别是整个部分都必须切除

我试着回应每个人的评论,我想我已经排除了这些事情中的大部分是一个问题,但我只剩下目前的反常行为。关于这一点,我能读到的更多的是,一些形式的复制字符串可能会导致内存溢出,这有可能吗

#include <iostream>
#include <fstream>
#include <windows.h>
#include <string>
#include <vector>
#include <stdio.h>
#include <tchar.h>
#include <algorithm>
#include <string>

using namespace std;

bool caseInsensitiveStringCompare( const std::string& str1, const std::string& str2 );

int main(int argc, char* argv[]) {

    const string path = "E:\\util\\bin\\";
    const string procName = "procReal.exe";
    const string argToFilter = "-t";


    string origValue;
    string passedValue;

    for(int i = 1; i < argc; i++)
    {
        origValue.append(" ").append(argv[i]);
    }

    for(int i = 1; i < argc; i++)
    {
        if (!caseInsensitiveStringCompare(argv[i],argToFilter))
        {
            passedValue.append(" ").append(argv[i]);
        }
        else
        {
            i++; // skip over argument and it's value
        }

    }

    const LPCTSTR exeModule = (path+procName).c_str();

    std::vector<char> chars(passedValue.c_str(), passedValue.c_str() + passedValue.size() + 1u);
    LPTSTR exeArgs = &chars[0];


    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    GetStartupInfo(&si);

    FILE* traceFile;
  traceFile = fopen ((path+"lastRun.txt").c_str(), "w");  // This causes exeModule to change value for unknown reasons???
  fprintf(traceFile, "orig: %s%s\n", exeModule, origValue.c_str());
  fprintf(traceFile, "%s%s\n", exeModule, exeArgs);

  SetLastError(0);

    // Start the child process.
    if( !CreateProcess( exeModule,   // use module name with args for exeArgs
        exeArgs,        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        TRUE,          // 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
    )
    {
        FILE* myfile;
        myfile = fopen ((path+"error.txt").c_str(), "w");
        fprintf(myfile, "CreateProcess failed (%d).\n", int(GetLastError()));
        fclose(myfile);
    }

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );

    DWORD exit_code;
    GetExitCodeProcess(pi.hProcess, &exit_code);

    fprintf(traceFile, "Exit Code: %d\n", int(exit_code));
    fclose(traceFile);

    // Close process and thread handles.
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    return exit_code;
}

bool caseInsensitiveStringCompare( const std::string& str1, const std::string& str2 ) {
    std::string str1Cpy( str1 );
    std::string str2Cpy( str2 );
    std::transform( str1Cpy.begin(), str1Cpy.end(), str1Cpy.begin(), ::tolower );
    std::transform( str2Cpy.begin(), str2Cpy.end(), str2Cpy.begin(), ::tolower );
    return ( str1Cpy == str2Cpy );
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
bool caseInsensitiveStringCompare(常量std::string和str1,常量std::string和str2);
int main(int argc,char*argv[]){
常量字符串path=“E:\\util\\bin\\”;
常量字符串procName=“procReal.exe”;
常量字符串argToFilter=“-t”;
字符串或值;
字符串passedValue;
对于(int i=1;i
最明显的问题是不能说
(path+procName).c_str()
,因为它构建的临时字符串对象会立即被丢弃,从而使返回的指针无效。我还非常怀疑是否假定
向量的元素必然是连续的

更正的字符串处理代码应如下所示:

    string passedValue(procName);  // First element of command line MUST be module name

    ...

    const string exeModuleString(path + procName);
    const LPCTSTR exeModule = exeModuleString.c_str();

    LPTSTR exeArgs = new char[passedValue.size() + 1];
    passedValue.copy(exeArgs, passedValue.size());
    exeArgs[passedValue.size()] = '\0';
    {
        DWORD err = GetLastError();
        FILE* myfile;
        myfile = fopen ((path+"error.txt").c_str(), "w");
        fprintf(myfile, "CreateProcess failed (%d).\n", int(err));
        fclose(myfile);
    }

(这可能不是最好的方法,我不经常使用C++。但是它应该正确工作) 已更正的错误处理代码(确保立即读取最后一个错误代码)应如下所示:

    string passedValue(procName);  // First element of command line MUST be module name

    ...

    const string exeModuleString(path + procName);
    const LPCTSTR exeModule = exeModuleString.c_str();

    LPTSTR exeArgs = new char[passedValue.size() + 1];
    passedValue.copy(exeArgs, passedValue.size());
    exeArgs[passedValue.size()] = '\0';
    {
        DWORD err = GetLastError();
        FILE* myfile;
        myfile = fopen ((path+"error.txt").c_str(), "w");
        fprintf(myfile, "CreateProcess failed (%d).\n", int(err));
        fclose(myfile);
    }
您的代码报告了错误的错误代码,因为调用fopen()会更改它。(创建覆盖现有文件的新文件时,最后一个错误代码设置为
error\u ready\u EXISTS

有两个更广泛的问题,在您的环境中可能重要,也可能不重要。首先,您使用argv[]为新流程构建命令行;这意味着命令行解析(如中所述)将应用两次(一次由进程应用,一次由子进程应用),如果命令行包含引号或反斜杠等特殊字符,则可能会导致问题。理想情况下,在一般情况下,您可以调用GetCommandLine()。(当然,这使得解析字符串以删除额外参数变得更加困难。)

其次,您显然是在ANSI模式下构建代码。如果命令l