VC下运行DOS命令解决方案

VC下运行DOS命令解决方案
2009-12-23 11:13

VC下运行DOS命令解决方案
问题:
在VC下想运行DOS命令,比如copy、dir、del等内部命令   
   是想直接运行这些命令,而不是调用相同功能的API函数   
   我的运行方法如下:   
   STARTUPINFO                      stInfo;   
   PROCESS_INFORMATION      piInfo;   
   memset(&stInfo,0,sizeof(stInfo));   
   memset(&piInfo,0,sizeof(piInfo));   
   stInfo.cb=sizeof(STARTUPINFO);         
   GetStartupInfo(&stInfo);   
   char    szCmd[1000]    =    {"del    c://a.txt"};   
   int    iCode    =    CreateProcess(NULL,szCmd,NULL,NULL,FALSE,CREATE_NO_WINDOW,//CREATE_NEW_CONSOLE,   
   NULL,NULL,&stInfo, &piInfo);   
    
   iCode    =    WinExec(szCmd,SW_HIDE);   
    
   iCode    =    (int)ShellExecute    (NULL,"open",szCmd,NULL,NULL,SW_HIDE);   
    
   三种方法都不行,都提示找不到文件名。   
   我猜想可能是找不到DOS内部命令对应的文件的缘故   
    
   如何直接调用DOS下的命令而不用任何处理就执行呢?   

解决方案:

使用WinExec命令   
    
   ⑴ 函数原型:UINT    WinExec(LPCSTR    lpCmdLine,    UINT    uCmdShow);   
    
   ⑵ 参数:lpCmdLine:指向一个空结束的字符串,串中包含将要执行的应用程序的命令行。   
    
   uCmdShow:定义Windows应用程序的窗口如何显示,并为CreateProcess函数提供STARTUPINFO参数的wShowWindow成员的值。   
    
   ⑶ 返回值:   
    
   若函数调用成功,则返回值大于31。若函数调用失败,则返回值为下列之一:   
    
   ① 0:系统内存或资源已耗尽。   
    
   ② ERROR_BAD_FORMAT:EXE文件无效。   
    
   ③ ERROR_FILE_NOT_FOUND:指定的文件未找到。   
    
   ④ ERROR_PATH_NOT_FOUND:指定的路径未找到。   
    
   虽然Microsoft认为WinExec已过时,但是在许多时候,简单的WinExec函数仍是运行新程序的最好方式。简单地传送作为第一个参数的 命令行,还需要决定如何显示程序的第二个参数。通常,将其设置为SW_SHOW,也可尝试SW_MINIMIZED或SW_MAXIMIZED。 WinExec不允许用CreateProcess获得的所有选项,而它的确简单。   
    
   3    使用ShellExecute命令   
    
   ⑴ 函数原型:   
    
   HINSTANCE    ShellExecute(HWND    hwnd,    LPCTSTR    lpOperation,    LPCTSTR    lpFile,    LPCTSTR    lpParameters,    LPCTSTR    lpDirectory,    INT    nShowCmd);   
    
   ⑵ 参数:   
    
   hwnd:指向父窗口的窗口句柄。此窗口接收应用程序产生的任何信息框。   
    
   lpOperation:一个空结束的字符串地址,此字符串指定要执行的操作。下面的操作字符串是有效的:   
    
   "open"   
    
   此函数打开由参数lpFile指定的文件,此文件可以是一个可执行文件或文档文件,也可是一个文件夹。   
    
   "print"   
    
   此函数打印由参数lpFile指定的文件,此文件应是一个文档文件,假如此文件是一个可执行文件,则打开此文件。   
    
   "explore"   
    
   此函数搜索由参数lpFile指定的文件夹,此文件应是一个文档文件,   
    
   此参数可以为空。这种情况下,函数用于打开由参数lpFile指定的文件。   
    
   lpFile:一个空结束的字符串地址,此字符串指定要打开或打印的文件或者是要打开或搜索的文件夹。   
    
   lpParameters:假如参数lpFile指定一个可执行文件,lpParameters则是一个空结束的字符串地址,此字符串指定要传递给应用程序的参数。假如lpFile指定一个文档文件,lpParameters应为空。   
    
   lpDirectory:一个空结束的字符串地址,此字符串指定默认目录。   
    
   nShowCmd:假如lpFile指定一个可执行文件,nShowCmd表明应用程序打开时如何显示。假如lpFile指定一个文档文件,nShowCmd应为空。   
    
   ⑶ 返回值:   
    
   若函数调用成功,则返回值大于32,否则为一个小于等于32的错误值。   
    
   说明:可以用此函数打开或搜索一个外壳文件夹。打开文件夹可用下面任何一种形式:   
    
   ShellExecute(handle,    NULL,    path_to_folder,    NULL,    NULL,    SW_SHOWNORMAL);   
    
   或   
    
   ShellExecute(handle,    "open",    path_to_folder,    NULL,    NULL,    SW_SHOWNORMAL);   
    
   搜索文件夹,可用如下形式   
    
   ShellExecute(handle,    "explore",    path_to_folder,    NULL,    NULL,    SW_SHOWNORMAL);   
    
   ShellExecute命令虽已过时但易于得到。该命令向命令解释程序提出打开、浏览或打印文档或文件夹的请求,虽然可以用 ShellExecute运行程序,但通常只发送文档名,而命令解释程序则决定要运行那个程序。另外在打开目录文件夹时,ShellExecute命令非 常有用。   
    
   ⑷ 程序示例   
    
   下面通过一个例子来说名WinExec和ShellExecute的使用。下面程序有控制台程序示例,其使用两种不同的方法,打开文本文件。下面程序使用WinExec,并明确指定使用记事本程序。然后,使用ShellExecute,打开文本文件。   
    
   程序清单   
    
   #include     
    
   #include     
    
   void    main(int    argc,char    *argv[])   
    
   {   
    
   cout<<"Opening    with    WinExec/n";   
    
   if    (WinExec("notepad    readme.txt",SH_SHOW)<32)   
    
   MessagBox(NULL,"Cant    WinExec",NULL,MB_OK);   
    
   cout<<"Press    Enter/n";   
    
   MessagBox(NULL,"Press    OK    to    continue","Progrm    Launched",MB_OK);   
    
   cout<<"Opening    with    ShellExecute/n";   
    
   if    (ShellExecute    (NULL,"open",   
    
   "readme.txt",NULL,NULL,SW_SHOW)<(HANDLE)    32)   
    
   MessagBox(NULL,"Cant    ShellExecute/n",NULL,MB_OK);   
    
   }   
    
   4    使用CreateProcess命令   
    
   ⑴ 函数原型:   
    
   BOOL    CreateProcess(   
    
   LPCTSTR    lpApplicationName,   
    
   LPTSTR    lpCommandLine,   
    
   LPSECURITY_ATTRIBUTES    lpProcessAttributes,     
    
   LPSECURITY_ATTRIBUTES    lpThreadAttributes,     
    
   BOOL    bInheritHandles,     
    
   DWORD    dwCreationFlags,   
    
   LPVOID    lpEnvironment,     
    
   LPCTSTR    lpCurrentDirectory,     
    
   LPSTARTUPINFO    lpStartupInfo,     
    
   LPPROCESS_INFORMATION    lpProcessInformation     
    
   );   
    
   ⑵ 参数:   
    
   lpApplicationName:指向一个以空结尾的串,他指定了要执行的模块   
    
   lpCommandLine:指向一个以空结尾的串,该串定义了要执行的命令行。   
    
   lpProcessAttributes:指向一个SECURITY_ATTRIBUTES结构,该结构决定了返回的句柄是否可被子进程继承。   
    
   lpThreadAttributes:指向一个SECURITY_ATTRIBUTES结构,该结构决定了返回的句柄是否可被子进程继承。   
    
   bInheritHandles,:表明新进程是否从调用进程继承句柄。   
    
   dwCreationFlags:定义控制优先类和进程创建的附加标志。   
    
   lpEnvironment:指向一个新进程的环境块。   
    
   lpCurrentDirectory:指向一个以空结尾的串,该串定义了子进程的当前驱动器和当前目录。   
    
   lpStartupInfo:指向一个STARTUPINFO结构,该结构定义了新进程的主窗口将如何显示。   
    
   lpProcessInformation:指向PROCESS_INFORMATION结构,该结构接受关于新进程的表示信息。   
    
   ⑶ 返回值:   
    
   若函数调用成功,则返回值不为0;若函数调用失败,返回值为0。   
    
   ShellExecute和WinExec命令用于简单的作业。如果要完全控制一个新进程,就必须调用CreateProcess。   
    
   在上述参数中,参数lpStartupInfo是STARTUPINFO结构。可以用来设置控台的标题,新窗口的的初始大小和位置,及重定向标准输入 和输出。新程序通常可以忽略多数这些数据项,如果选择那样做的话。可以规定该结构体中的标志,已表明要设置的数据段。有时,不想设置任何信息,也必须传递 一个有效的指针给空结构。参数lpProcessInformation返回进程和线程句柄,还包括进程和线程ID。这些句柄拥有在参数 lpProcessAttributes和lpThreadAttributes中规定的访问。   
    
   要注意,针对CreateProcess的一些参数对控制台应用程序是特定的,而其它参数则对各种应用程序有用。大多数情况下,并不一定要填入 STARTUPINFO结构,但无论如何必须提供它。其返回值是布尔型的,而真正感兴趣的返回值发生于作为参数传送的结构中。CreateProcess 返回该结构中的进程ID及其句柄,以及初始线程ID及其句柄。可以将ID发送到其它进程,或使用句柄来控制新进程。

=================================================
void runcmd(CString cmd, char *buf, unsigned int bufsize, unsigned int delay)
{
    SECURITY_ATTRIBUTES sa;
    HANDLE hRead, hWrite;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
   
    if (!CreatePipe(&hRead, &hWrite, &sa, 0)) {
        return;
    }
   
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    si.cb = sizeof(STARTUPINFO);
    GetStartupInfo(&si);
    si.hStdError = hWrite;
    si.hStdOutput = hWrite;
    si.wShowWindow = SW_HIDE;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    if (!CreateProcess(NULL, (LPTSTR)(LPCTSTR)cmd, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
        return;
    }
    CloseHandle(hWrite);
    Sleep(delay);
    DWORD bytesRead;
    while (TRUE) {
        memset(buf, 0, bufsize);
        /* If the ReadFile function succeeds, the return value is nonzero. */
        if (ReadFile(hRead, buf, bufsize, &bytesRead, NULL) != NULL) {
            break;
        }
        Sleep(200);
    }
    CloseHandle(hRead);
    return;
}

void CYUVviewerDlg::ExecDosCmd()
{
    // TODO: Add your control notification handler code here
    CString cmd = "ipconfig";
    char *buf;
    unsigned int bufsize = 1024;
    unsigned int delay = 0;
    if ((buf = (char *)malloc(bufsize)) == NULL) {
        return;
    }
   
    memset(buf, 0, bufsize);
    runcmd(cmd, buf, bufsize, delay);
    //m_opt.Format("%s", buf);
    UpdateData(FALSE);
    free(buf);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值