error:Createprocess接收命令行的参数时,无法找到指定的文件。。

本文详细探讨了在使用CreateProcess函数时,不同编码设置导致的问题及解决方案,通过实例展示了如何在多字节工程下正确调用命令行参数,避免错误提示并确保程序顺利执行。

1、在cmd命令行中输入的命令是: E:\P2PDownLoadCall.exe “p2pdownload.exe -r image\boot.img” 结果,CreateProcess failed,而且 GetLastError的结果为2,找不到对应的文件。

2、我也没辙了,然后就用写死的路径 Text(“p2pdownload.exe -r image\boot.img”);来作为CreateProcess函数的第二个参数,结果竟可以成功。

3、我才明白,是cmd的输入是多字节的,而vs默认当前的工程为Unicode型,因此会调用CreateProcessW函数,遇到多字节的参数,肯定会保存错误,因此得出了“找不到相应的文件的错误”

4、为了验证我的错误,我将本工程改为多字节的,结果,程序就顺利执行了。默认调用的是CreateProcessA,会以多字节的形式处理参数,因此会无误地识别cmd命令行传进来的参数。

5、多字节的工程代码如下:

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>

int main( int argc, TCHAR ** argv )
{
    int nReturn = 1;
    if ( argc < 2 )
    {
        nReturn = 1;
        goto exit;
    }
    else
    {
        PROCESS_INFORMATION pi;
        STARTUPINFO si;
        DWORD dwExitCode = 1;
        TCHAR szCommand[500];

        ZeroMemory( &pi, sizeof( pi ) );
        ZeroMemory( &si, sizeof( si ) );
        si.cb = sizeof( si );
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;

        printf("argv[1]:%s\n",argv[1]);

        _tcscpy( szCommand, argv[1] );
        if ( CreateProcess( NULL, szCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) )
        {
            printf("CreateProcess succeeded!\n");
        } 
        else
        {
            printf("CreateProcess failed!GetLastError:%d\n",GetLastError());
            nReturn = 2;
            goto exit;
        }

        WaitForSingleObject( pi.hProcess, INFINITE );

        if ( GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
        {
            printf("GetExitCodeProcess succeeded,dwExitCode is %d\n",dwExitCode);
            nReturn = 0;
        } 
        else
        {
            printf("GetExitCodeProcess failed,dwExitCode is %d,GetLastError:%d\n",dwExitCode,GetLastError());
            nReturn = 3;
        }
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
        goto exit;

    }
exit:

    return nReturn;
}
// 实验一创建进程.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <iostream> #include <stdio.h> //创建子进程,与父进程执行相同的程序。 void StartClone(int nCloneID) { // 获取当前进程的可执行文件名。 TCHAR szFilename[MAX_PATH] ; :: GetModuleFileName( NULL, //一个模块的句柄。模块句柄跟一般的句柄不一样, //模块句柄指向的就是EXE和DLL等在虚拟地址空间的位置。 //如果该参数为NULL,该函数返回该应用程序全路径。 szFilename, MAX_PATH) ; // 格式化用于创建新进程的命令行,包括EXE文件名和克隆ID TCHAR szCmdLine[MAX_PATH]; :: sprintf(szCmdLine,"\"%s\"%d",szFilename,nCloneID); // 用于新进程的STARTUPINFO结构 STARTUPINFO si; :: ZeroMemory(reinterpret_cast <void*> (&si) , sizeof(si) ) ; si.cb = sizeof(si) ; // 必须是本结构的大小 // 返回的用于新进程的进程信息 PROCESS_INFORMATION pi; // 使用同一可执行文件和带有克隆ID的命令行创建新进程。 BOOL bCreateOK=::CreateProcess( szFilename, // 新进程的可执行文件名 szCmdLine, // 传给新进程的命令行参数 NULL, // 缺省的进程安全性 NULL, // 缺省的线程安全性 FALSE, // 不继承句柄 CREATE_NEW_CONSOLE, // 使用新的控制台 NULL, // 新的环境 NULL, // 当前目录 &si, // 启动信息 &pi) ; // 返回的进程信息 //不使用的句柄最好关掉 if (bCreateOK) { :: CloseHandle(pi.hProcess) ; :: CloseHandle(pi.hThread) ; } } int main(int argc, char* argv[] ) { // 进程的克隆ID int nClone(0) ; //第一个进程argc为1,以后每个进程命令行有两个参数, //其中第二个是克隆ID。 if (argc > 1) { // 从第二个参数中提取克隆ID :: sscanf(argv[1] , "%d" , &nClone) ; } // 显示进程的克隆ID std :: cout << "Process ID:" << :: GetCurrentProcessId() << ", Clone ID:" << nClone << std :: endl; // 创建新进程,其nClone为1-8 const int c_nCloneMax=8; if (nClone < c_nCloneMax) { :: Sleep(1000) ; StartClone(nClone+1) ; } // 等待输入一个字符,以便观察。输入一个字符后,程序结束。 std::cout<<"input a char:"; getchar(); std::cout<<"I'm stopped ... Bye-Bye"; return 0; } /* 思考题: 1.main函数的两个参数如何使用? 2.main函数是如何运行起来的? 3.运行后在系统任务管理器中查看所创建进程映像名是否相同? 4.父子进程运行同一可执行文件,如何能够区分出他们? 5.不同进程的克隆ID是如何获取到的? 6.如果在克隆ID为0的进程中创建克隆ID为1-8的进程,应该如何修改程序? */
最新发布
11-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值