打造自己的GUI专版命令行程序

本文介绍如何将命令行工具封装成图形用户界面应用程序。通过使用CreateProcess结合管道技术,解决了参数传递及结果回显的问题,并展示了具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

命令行下的工具效率高,速度快,但是当程序的参数太多时,却不易于使用。所以我们就给它做个界面封装一下,顺 便把我们的大名也加上呵呵为了方便说明我们选用一个比较简单的程序GetOS.exe它是MS04011工具包中的一个小 工具,主要用来探测目标系统的类型原程序和改造后的效果如图1和图2所示

  

实现思路:

    现在主要有两个问题需解决
    
1.怎样在GUI程序中把参数传递给CMD程序
    
2.怎样把结果传回到界面

    这两个问题可以用CreateProcess结合管道来解决,可以用CreateProcess创建CMD程序并传递需要参数
    执行完成后再将结果写到指定的管道中去,最后把管道的内容更新到界面程序的控件中。

 

 

结构说明:
    在开始之前先看几个比较重要的结构和API函数

    CreateProcess用来创建新的进程它的的原形如下:
    BOOL CreateProcess(
      LPCTSTR lpApplicationName,
                             
// pointer to name of executable module
      LPTSTR lpCommandLine,  // pointer to command line string
      LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes
      LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes
      BOOL bInheritHandles,  // handle inheritance flag
      DWORD dwCreationFlags, // creation flags
      LPVOID lpEnvironment,  // pointer to new environment block
      LPCTSTR lpCurrentDirectory,   // pointer to current directory name
      LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
      LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
    );
 
    lpApplicationName和lpCommandLine参数分别用于新进程用使用的文件名,和要传递给新进程的参数

字符串
    通常 把lpApplicationName置为NULL而在lpCommandLine中给出程序的全路径和参数字符串。
    bInheritHandles用来指定子进程是否继承主进程的句柄。
    lpStartupInfo是程序的要点,它用于指向一个STARTUPINFO结构,其定义如下:
    typedef 
struct _STARTUPINFO // si 
        DWORD   cb; 
        LPTSTR  lpReserved; 
        LPTSTR  lpDesktop; 
        LPTSTR  lpTitle; 
        DWORD   dwX; 
            DWORD   dwY; 
         DWORD   dwXSize; 
         DWORD   dwYSize; 
        DWORD   dwXCountChars; 
        DWORD   dwYCountChars; 
        DWORD   dwFillAttribute; 
        DWORD   dwFlags; 
        WORD    wShowWindow; 
        WORD    cbReserved2; 
        LPBYTE  lpReserved2; 
        HANDLE  hStdInput; 
        HANDLE  hStdOutput; 
        HANDLE  hStdError; 
    }
 STARTUPINFO, *LPSTARTUPINFO; 

    这个结构有很多项,需要使用的有以下几项

        WORD    wShowWindow; 
//是否显示调用
        HANDLE  hStdOutput;  //子程序输出句柄 
        HANDLE  hStdError;   //子程序错误输出句柄
        DWORD   dwFlags;      //创建子进程的一组标志

    只要让hStdOutput句柄指向管道的写句柄,程序执行后结果就保存在管道中了。

 

 

参数传递:

    跟据上面的说明在创建子进程时,可以这样构建参数传递命令

    
char szCMD[]="c:/getos.exe";
    UpdateData(
true);
    
if(m_szIP!="")    /m_szIP为EDIT控件用于接受目标IP
    
{
        
char* szIP=m_szIP.LockBuffer();
        sprintf(szCMD,
"%s %s",szCMD,szIP);//构建参数传递命令
        CreateProcess(NULL,szCMD,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi);//创建进程
    }


结果写入管道:

    SECURITY_ATTRIBUTES sa;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    HANDLE hRead;
    HANDLE hWrite;

    sa.nLength 
= sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor 
= NULL;
    sa.bInheritHandle 
= TRUE;
    CreatePipe(
&hRead,&hWrite,&sa,0);    //创建管道

    si.cb 
= sizeof(STARTUPINFO);
    GetStartupInfo(
&si);            //设置启动信息
    si.hStdError = hWrite;
    si.hStdOutput 
= hWrite;            //将子进程输出结果写出管道
    si.wShowWindow = SW_HIDE;        //隐式调用子程序
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    CreateProcess(NULL,szCMD,NULL,NULL,TRUE,NULL,NULL,NULL,
&si,&pi);

    把子程序的输出写入管道,当子程序执行后就可以用ReadFile来读取管道的内容

读取管道内容:

    
char buffer[4096= {0};
    DWORD bytesRead;
    ReadFile(hRead,buffer,
4095,&bytesRead,NULL);//读取管道内容
    m_edit+=buffer;                //更新显示控件
    UpdateData(false);

 

 

加载资源:
    
    在完成上面的工作以前应该先把CMD程序以资源的形式加载进去,在使用时再释放出来。加载资源可按

以下步骤
    在Resource右键选择IMPORT选择文件然后输入类型(比如GETOS)就行了,在使用时可用以下代码释放

    HRSRC hr
=FindResource(0,MAKEINTRESOURCE(IDR_GETOS),"GETOS");/查找资源
    
if(hr==NULL)
        MessageBox(
"hr error");

    dwSize
=SizeofResource(NULL,hr);

    HGLOBAL hg
=LoadResource(NULL,hr);//加载资源

    
if(hg==NULL)
        MessageBox(
"hg error");

    LPSTR lp
=(LPSTR)LockResource(hg);//锁定资源

    
if(lp==NULL)
        MessageBox(
"lp error");

    HANDLE hFile;
    hFile 
= CreateFile("c:/getos.exe",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);//创建文件
    if(hFile == NULL)
        MessageBox(
"file error");
    WriteFile(hFile,(LPCVOID)LockResource(hg),dwSize,
&dwWritten,NULL);//写入文件
    CloseHandle(hFile);
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值