要把如下的两篇文章结合起来看:

  1. qt怎么获取硬盘序列号,是不是没戏?

    http://www.qtcn.org/bbs/simple/?t65637.html

system("wmic path win32_physicalmedia get SerialNumber");

  1. 在VC下执行DOS命令并得到输出

    https://www.cnblogs.com/cnarg/archive/2011/02/20/1959292.html

http://topic.csdn.net/u/20081118/22/644899d5-43f3-4461-b101-f2c9838ee401.html 
   a.   system("md c:\\12"); 
   b.   WinExec("Cmd.exe /C md c:\\12", SW_HIDE); 
   c.   ShellExecute 
   ShellExecute(NULL,"open","d:\\WINDOWS\\system32\\cmd.exe","/c md d:\\zzz","",SW_SHOW); 
   d.   CreateProcess

改变DOS程序的标准输出,用一个管道的写端口替换他,然后windows程序从管道的读端口读出来。 
下面这个示例的函数可以把给定的DOS命令执行一遍,并把DOS下的输出内容记录在buffer中。同时示范了匿名管道重定向输出的用法: 
------------------------------------------------------------------------------------- 
BOOL CDOSDlg::ExecDosCmd() 
{    
#define EXECDOSCMD "dir c:" //可以换成你的命令

SECURITY_ATTRIBUTES sa; 
HANDLE hRead,hWrite;

sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
sa.lpSecurityDescriptor = NULL; 
sa.bInheritHandle = TRUE; 
if (!CreatePipe(&hRead,&hWrite,&sa,0)) 

    return FALSE; 

char command[1024];    //长达1K的命令行,够用了吧 
strcpy(command,"Cmd.exe /C "); 
strcat(command,EXECDOSCMD); 
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; 
//关键步骤,CreateProcess函数参数意义请查阅MSDN 
if (!CreateProcess(NULL, command,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) 

    CloseHandle(hWrite); 
    CloseHandle(hRead); 
    return FALSE; 

CloseHandle(hWrite);

char buffer[4096] = {0};          //用4K的空间来存储输出的内容,只要不是显示文件内容,一般情况下是够用了。
DWORD bytesRead; 
while (true) 

    if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL) 
   break; 
    //buffer中就是执行的结果,可以保存到文本,也可以直接输出 
    AfxMessageBox(buffer);   //这里是弹出对话框显示 

CloseHandle(hRead); 
return TRUE; 
        }

------------------------------------------------------------------------------------------------------------------------

;若函数调用失败,返回值为0。 
ShellExecute和WinExec命令用于简单的作业。如果要完全控制一个新进程,就必须调用CreateProcess。 
在上述参数中,参数lpStartupInfo是STARTUPINFO结构。可以用来设置控台的标题,新窗口的的初始大小和位置,及重定向标准输入和输出。新程序通常可以忽略多数这些数据项,如果选择那样做的话。可以规定该结构体中的标志,已表明要设置的数据段。有时,不想设置任何信息,也必须传递一个有效的指针给空结构。参数lpProcessInformation返回进程和线程句柄,还包括进程和线程ID。这些句柄拥有在参数lpProcessAttributes和lpThreadAttributes中规定的访问。 
要注意,针对CreateProcess的一些参数对控制台应用程序是特定的,而其它参数则对各种应用程序有用。大多数情况下,并不一定要填入STARTUPINFO结构,但无论如何必须提供它。其返回值是布尔型的,而真正感兴趣的返回值发生于作为参数传送的结构中。CreateProcess返回该结构中的进程ID及其句柄,以及初始线程ID及其句柄。可以将ID发送到其它进程,或使用句柄来控制新进程。

-----------------------------------------------------------------------------------------------------

如何在vc中执行多条dos命令

STARTUPINFO   si;   
ZeroMemory(&si,   sizeof(si));   
si.cb   =   sizeof   STARTUPINFO;   
si.wShowWindow   =   SW_HIDE;   
si.dwFlags   =   STARTF_USESHOWWINDOW   |   STARTF_USESTDHANDLES;

PROCESS_INFORMATION   pi;   
BOOL   res   =   CreateProcess(NULL,   
"c:\\winnt\\system32\\cmd.exe/c   md   c:\\12", NULL, NULL, NULL, NORMAL_PRIORITY_CLASS   |   CREATE_NO_WINDOW, NULL, NULL, &si, &pi);   
if   (TRUE   ==   res)   
{   
//等待进程执行完毕   
WaitForSingleObject(pi.hProcess,   INFINITE);       
CloseHandle(pi.hProcess);   
CloseHandle(pi.hThread);   
}   
在完毕以后,再启动一个createprocess

给你一个重定向输出到edit控件的例子   
  {   
  SECURITY_ATTRIBUTES   sa;   
  HANDLE   hRead,hWrite;   
  sa.nLength   =   sizeof(SECURITY_ATTRIBUTES);   
  sa.lpSecurityDescriptor   =   NULL;   
  sa.bInheritHandle   =   TRUE;   
  if   (!CreatePipe(&hRead,&hWrite,&sa,0))   
  {   
  MessageBox("Error   On   CreatePipe()");   
  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,"c:\\winnt\\system32\\cmd.exe   /c   dir"   
                  ,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))   
  {   
  DWORD   dw   =   GetLastError();   
                  MessageBox("Error   on   CreateProcess()");   
                  return;   
  }   
  CloseHandle(hWrite);   
  char   buffer[4096]   =   {0};   
  DWORD   bytesRead;     
  while   (true)   
  {   
  if   (ReadFile(hRead,buffer,4095,&bytesRead,NULL)   ==   NULL)   
  break;   
  m_strResult+=   buffer;//m_strResult为edit控件关联变量   
  UpdateData(false);   
  Sleep(200);     
  }     
  }   
Top

7 楼fanqing(火影忍者+28%(准备学习进程/线程))回复于 2005-01-13 18:01:57 得分 0

不知你是否用过这样的程序,他们本身并没有解压缩的功能,而是调用DOS程序PKZIP完成ZIP包的解压缩。但是在程序运行时又没有DOS控制台的窗口出现而且一切本应该在DOS下显示的信息都出现在了那个安装程序的一个文本框里。这种设计既美观又可以防止少数眼疾手快的用户提前关了你的DOS窗口。   
  现在就来讨论一下,如何用匿名管道技术实现这个功能。   
  管道技术由来已久,相信不少人对DOS命令里的管道技术最为熟悉。当我们type一个文件的时候如果想让他分页现实可以输入   
  C:\>type   autoexec.bat|more   
  这里"|"就是管道操作符。他以type输出的信息为读取端,以more的输入端为写入端建立的管道。   
  Windows中使用较多的管道也是匿名管道,它通过API函数CreatePipe创建。   
  BOOL   CreatePipe(   
                        PHANDLE   hReadPipe,   //   指向读端句柄的指针   
                        PHANDLE   hWritePipe,   //   指向写端句柄的指针   
                        LPSECURITY_ATTRIBUTES   lpPipeAttributes,   //   指向安全属性结构的指针   
                        DWORD   nSize   //   管道的容量   
  );   
  上面几个参数中要注意hReadPipe,hWritePipe是指向句柄的指针,而不是句柄(我第一次用的时候就搞错了)。nSize一般指定为0,以便让系统自己决定管道的容量。现在来看安全属性结构,SECURITY_ATTRIBUTES。   
  typedef   struct   _SECURITY_ATTRIBUTES   {   //   sa     
                        DWORD   nLength;     
                        LPVOID   lpSecurityDescriptor;     
                        BOOL   bInheritHandle;     
  }   SECURITY_ATTRIBUTES;     
  nLength是结构体的大小,自然是用sizeof取得了。lpSecurityDescriptor是安全描述符(一个C-Style的字符串)。bInheritHandle他指出了安全描述的对象能否被新创建的进程继承。先不要管他们的具体意义,使用的时候自然就知道了。   
  好,现在我们来创建一个管道     
  HANDLE   hReadPipe,   hWritePipe;   
  SECURITY_ATTRIBUTES   sa;   
  sa.nLength   =   sizeof(SECURITY_ATTRIBUTES);   
  sa.lpSecurityDescriptor   =   NULL;   //使用系统默认的安全描述符   
  sa.bInheritHandle   =   TRUE;   //一定要为TRUE,不然句柄不能被继承。   
  CreeatePipe(&hReadPipe,&hWritePipe,&sa,0);   
  OK,我们的管道建好了。当然这不是最终目的,我们的目的是把DOS上的一个程序输出的东西重定向到一个Windows程序的Edit控件。所以我们还需要先启动一个DOS的程序,而且还不能出现DOS控制台的窗口(不然不就露馅了吗)。我们用CreateProcess创建一个DOS程序的进程。   
  BOOL   CreateProcess(   
                        LPCTSTR   lpApplicationName,   //   C-style字符串:应用程序的名称     
                        LPTSTR   lpCommandLine,   //   C-style字符串:执行的命令   
                        LPSECURITY_ATTRIBUTES   lpProcessAttributes,   //   进程安全属性   
                        LPSECURITY_ATTRIBUTES   lpThreadAttributes,   //   线程安全属性   
                        BOOL   bInheritHandles,   //   是否继承句柄的标志   
                        DWORD   dwCreationFlags,   //   创建标志   
                        LPVOID   lpEnvironment,   //   C-Style字符串:环境设置   
                        LPCTSTR   lpCurrentDirectory,   //   C-Style字符串:执行目录   
                        LPSTARTUPINFO   lpStartupInfo,   //   启动信息   
                        LPPROCESS_INFORMATION   lpProcessInformation   //   进程信息   
  );   
  先别走,参数是多了点,不过大部分要不不用自己填要不填个NULL就行了。lpApplication随便一点就行了。lpCommandLine可是你要执行的命令一定要认真写好。来,我们瞧瞧lpProcessAttributes和lpThreadAttributes怎么设置。哎?这不就是刚才那个吗。对阿,不过可比刚才简单。由于我们只是创建一个进程,他是否能在被继承不敢兴趣所以这两个值全为NULL。bInHeritHandles也是一定要设置为TRUE的,因为我们既然要让新的进程能输出信息到调用他的进程里,就必须让新的进程继承调用进程的句柄。我们对创建的新进程也没什么别的苛求,所以dwCreationFlags就为NULL了。lpEnvironment和lpCurrentDirectory根据你自己的要求是指一下就行了,一般也是NULL。接下来的lpStartupInfo可是关键,我们要认真看一下。   
  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;     
  倒!这么多参数,一个一个写肯定累死了。没错,MS早就想到会累死人。所以提供救人一命的API函数GetStartupInfo。   
  VOID   GetStartupInfo(   
                        LPSTARTUPINFO   lpStartupInfo   
  );   
  这个函数用来取得当前进程的StartupInfo,我们新建的进程基本根当前进程的StartupInfo差不多,就借用一下啦。然后再小小修改一下即可。   
  我们要改的地方有这么几个:cb,dwFlags,hStdOutput,hStdError,wShowWindow。先说cb,他指的是STARTUPINFO的大小,还是老手法sizeof。再说wShowWindow,他制定了新进程创建时窗口的现实状态,这个属性当然给为SW_HIDE了,我们不是要隐藏新建的DOS进程吗。哈哈,看到hStdOutput和hStdError,标准输出和错误输出的句柄。关键的地方来了,只要我们把这两个句柄设置为hWrite,我们的进程一旦有标准输出,就会被写入我们刚刚建立的匿名管道里,我们再用管道的hReadPipe句柄把内容读出来写入Edit控件不就达到我们的目的了吗。呵呵,说起来也真是听容易的阿。这几个关键参数完成了以后,千万别忘了dwFlags。他是用来制定STARTUPINFO里这一堆参数那个有效的。既然我们用了hStdOutput,hStdError和wShowWindow那dwFlags就给为STARTF_USESHOWWINDOW   |   STARTF_USESTDHANDLES。   
  好了,现在回到CreateProcess的最后一个参数lpProcessInformation(累!)。呵呵,这个参数不用自己填了,他是CreateProcess返回的信息,只要给他一个PROCESS_INFORMATION结构事例的地址就行了。   
  大功高成了,我们管道一端连在了新进程的标准输出端了,一端可以自己用API函数ReadFile读取了。等等,不对,我们的管道还有问题。我们把hWrite给了hStdOutput和hStdError,那么在新的进程启动时就会在新进程中打开一个管道写入端,而我们在当前进程中使用了CreatePipe创建了一个管道,那么在当前进程中也有这个管道的写入端hWrite。好了,这里出现了一个有两个写入端和一个读出端的畸形管道。这样的管道肯定是有问题的。由于当前进程并不使用写端,因此我们必须关闭当前进程的写端。这样,我们的管道才算真正的建立成功了。来看看VC++写的源程序:   
  /*     
    *   通过管道技术,将dir   /?的帮助信息输入到MFC应用程序的一个CEdit控件中。   
    *   VC++6.0   +   WinXP   通过     
    *     
    *   detrox,   2003     
    */   
  void   CPipeDlg::OnButton1()     
  {     
      SECURITY_ATTRIBUTES   sa;   
      HANDLE   hRead,hWrite;   
      sa.nLength   =   sizeof(SECURITY_ATTRIBUTES);   
      sa.lpSecurityDescriptor   =   NULL;   
      sa.bInheritHandle   =   TRUE;   
      if   (!CreatePipe(&hRead,&hWrite,&sa,0))   {   
        MessageBox("Error   On   CreatePipe()");   
            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,"c:\\windows\\system32\\cmd.exe/c   dir   /?"   
                  ,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))   {   
                  MessageBox("Error   on   CreateProcess()");   
                  return;   
      }   
      CloseHandle(hWrite);   
      char   buffer[4096]   =   {0};   
      DWORD   bytesRead;     
      while   (true)   {   
              if   (ReadFile(hRead,buffer,4095,&bytesRead,NULL)   ==   NULL)   
                      break;   
              m_Edit1   +=   buffer;   
              UpdateData(false);   
              Sleep(200);     
      }     
  }

MFC如何获取硬盘的序列号的更多相关文章

  1. Windows ,获取硬盘物理序列号(VC++)

    #include <windows.h> BOOL GetHDID(PCHAR pIDBufer) {     HANDLE hDevice=NULL;    hDevice=::Crea ...

  2. java通过jni方式获取硬盘序列号(windows,linux)

    linux系统java通过jni方式获取硬盘序列号 http://blog.csdn.net/starter110/article/details/8186788 使用jni在windows下读取硬盘 ...

  3. delphi 获取硬盘序列号、cpu号、bios号、网卡号

    delphi 获取硬盘 序列号 function GetIdeNum: String; type TSrbIoControl = packed record HeaderLength : ULONG; ...

  4. Windows 下获取硬盘序列号

    只获取序列号 以下任意一条命令都可以: wmic diskdrive get serialnumber wmic path win32_physicalmedia get SerialNumber w ...

  5. 获取硬盘序列号的Fortran程序

    以前写了个获取硬盘序列号的fortran程序,但未经实证 program FortranDemo Use Kernel32 Implicit None Interface SUBROUTINE Get ...

  6. vc 获取 硬盘序列号 和 cpu

    vc 获取 硬盘序列号 和 cpu 唯一iD的方法?如题---------网上找来很多资料 也没找到, 要支持xp win7 32/64 系统下都能获取 硬盘序列号 和cpu ID 哪位朋友帮帮忙: ...

  7. c/c++获取硬盘序列号

    最近在接触软件注册模块,需要获取硬盘序列号来生成注册码. 硬盘序列号,英文名:Hard Disk Serial Number,该号是硬盘厂家为区别产品而设置的,是唯一的.网上搜索一下,发现获取硬盘序列 ...

  8. 用hdparm获取硬盘参数

    hdparm是Linux下一款能够获取和设置SATA/IDE设备参数的工具. 1.获取硬盘参数 $ sudo hdparm -i /dev/sda$ sudo hdparam -i /dev/sda ...

  9. 获取sim卡序列号

    //获取sim卡序列号TelephoneManager TelephonyManager manager = (TelephonyManager)getSystemService(Context.TE ...

随机推荐

  1. 【来龙去脉系列】深入理解DIP、IoC、DI以及IoC容器

    摘要 面向对象设计(OOD)有助于我们开发出高性能.易扩展以及易复用的程序.其中,OOD有一个重要的思想那就是依赖倒置原则(DIP),并由此引申出IoC.DI以及Ioc容器等概念.通过本文我们将一起学 ...

  2. STM32的CRC32 测试代码

    // STM32 CRC32 Test App - sourcer32@gmail.com #include <windows.h> #include <stdio.h> DW ...

  3. nginx源码学习 资料

    首先要做的当然是下载一份nginx源码,可以从nginx官方网站下载一份最新的. 看了nginx源码,发现这是一份完全没有注释,完全没有配置文档的代码. 现在你最希望要的是一份注释版的nginx源码, ...

  4. Virtualenv教程

    虚拟环境简介 VirtualEnv用于在一台机器上创建多个独立的Python虚拟运行环境,多个Python环境相互独立,互不影响,它能够: 在没有权限的情况下安装新套件 不同应用可以使用不同的套件版本 ...

  5. 娓娓道来c指针 (7)指针运算

    (7)指针运算 在前几篇文章中,我们已经见过指针运算的使用场景,并多次使用指针运算来进行验证. 这里我们来特别地总结下.指针运算的本质含义. 在c语言中.如果p.pa.pb都是某种类型的指针,这种运算 ...

  6. 11i and R12 Table Count in Different Module

    Advertisement Module 11i Tables R12 Tables New Tables AR 551 616 118 BOM 264 337 73 GL 186 309 140 A ...

  7. C++关键字之virtual

    from://http://blog.csdn.net/xuyuanfan/article/details/9935533 在C++中是没有接口的,要真正实现java中的interface功能,需要使 ...

  8. 一分钟掌握Android spinner下拉框

    Android 自带的spinner下拉框控件是一个不错的系统控件.主要有两种实现方式: 1.静态的spinner 在res\values中加入一个city资源数组文件 2 <resources ...

  9. SharePoint 设置客户端上传文件大小

    in sharepoint 2013, 2016 , there is a limitatoin on the size of the uploading files , default size f ...

  10. java 8 stream特性

    在Java 8的新功能特性中,最棒的特性就是允许我们去表达我们想要完成什么而不是要怎样做.这正是循环的不足之处.要确保循环的灵活性是需要付出代价的.return.break 或者 continue都会 ...