程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 打造自己的GUI專版命令行程序

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

編輯:.NET實例教程

命令行下的工具效率高,速度快,但是當程序的參數太多時,卻不易於使用。所以我們就給它做個界面封裝一下,順 便把我們的大名也加上呵呵為了方便說明我們選用一個比較簡單的程序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);

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved