【问题标题】:ERROR_FILE_NOT_FOUND while CreateProcessCreateProcess 时出现 ERROR_FILE_NOT_FOUND
【发布时间】:2016-11-24 12:09:24
【问题描述】:

尝试使用CreateProcess运行记事本:

void _tmain( int argc, TCHAR *argv[] )
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

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



    // Start the child process. 
    if( !CreateProcess( "notepad.exe",   // No module name (use command line)
        NULL,        // 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
        ) 
    {
        printf( "CreateProcess failed (%d).\n", GetLastError() );
        return;
    }

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

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

在输出 2 中有错误。这意味着ERROR_FILE_NOT_FOUND。我应该从哪里开始寻找问题?是不是说找不到notepad.exe

【问题讨论】:

    标签: winapi visual-c++ createprocess


    【解决方案1】:

    lpApplicationName 参数必须提供应用程序的完整路径,而不仅仅是其名称。

    更准确地说:

    字符串可以指定模块的完整路径和文件名 执行或者它可以指定一个部分名称。在部分情况下 名称,该函数使用当前驱动器和当前目录 完成规范。该函数不会使用搜索路径。 该参数必须包含文件扩展名;无默认 假定扩展名。

    但你应该不在notepad.exe 的当前文件夹中。因此,如果您只想使用名称,请将其设置在第二个参数 lpCommandLine 中。请注意,此字符串不是常量,因为它是这样定义为LPTSTR 参数的:

    BOOL WINAPI CreateProcess(
    _In_opt_ LPCTSTR lpApplicationName,
    _Inout_opt_ LPTSTR lpCommandLine,[...]

    所以你有 2 个变体:

    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    
    WCHAR CommandLine[] = L"notepad.exe";
    if( CreateProcess( 0,   // No module name (use command line)
        CommandLine,        // 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
        ) 
    {
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }
    

    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    
    if( CreateProcess( L"c:\\windows\\notepad.exe",  
        0,        // 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
        ) 
    {
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }
    

    【讨论】:

    • 并非所有人都将 Windows 安装到 C:\Windows,因此您不应硬编码 Windows 文件夹的路径。请改用GetWindowsDirectory()。或者,check the Registry 查看是否已注册记事本的完整路径。
    • @RemyLebeau - 当然你对记事本的路径是正确的。但我的目标是在CreateProcessW 中显示第一个和第二个参数的用法,这不是最终代码,而是最大的简单演示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 2019-10-31
    • 2023-03-06
    • 2023-01-13
    相关资源
    最近更新 更多