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

  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. scrum vs devops vs sre

    DevOps&SRE 超越传统运维之道[北京站] IT大咖说 - 大咖干货,不再错过 http://www.itdks.com/eventlist/detail/908

  2. 使用GIT进行源码管理——GIT托管服务2018

    我曾经介绍过几个在线的GIT托管服务,然而时过境迁,发生了不少变化,便写了此文章,在新的一年重新更新一下:   国外托管网站: 国外托管网站比起国内的来相对靠谱点,但一个主要缺点是网速较慢,并且可能在 ...

  3. IDA .edata .rdata .idata .text segments

    .rdata is for const data. It is the read only version of the .data segment. .idata holds the import ...

  4. 使用cwRsync实现windows下文件定时同步

    1.参考文献: 使用cwRsync实现windows下文件定时同步(备份) 文件同步工具CwRsync的使用方法及常用命令详解 2.背景: 当前的SCADA架构中,有1台Server,5台FE,还有1 ...

  5. Temporary ASP.Net Files探究

    了解.net平台的兄弟都知道,.net也是采用动态编译的也就是说我们常说的build生成的dll只是中间代码而在web第一次请求的时候才是真正意义上的编译生成二进制代码这也就是为什么刚编译完第一次打开 ...

  6. ASP.Net中关于WebAPI与Ajax进行跨域数据交互时Cookies数据的传递

    本文主要介绍了ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据传递的相关知识.具有很好的参考价值.下面跟着小编一起来看下吧 前言 最近公司项目进行架构调整,由原来的三层架构改 ...

  7. How to Set Up DTrace to Detect PHP Scripting Problems on Oracle Linux

    http://www.oracle.com/technetwork/articles/servers-storage-admin/php-dtrace-linux-2062229.html

  8. 利用Ffmpeg获得flv视频缩略图和视频时间的代码

    问题描述:获得flv视频的缩略图和视频时间长度 谷歌了半天发现可以使用Ffmpeg获得视频的一些信息,先介绍一下FFMEPG 这里简单说一下:FFmpeg是用于录制.转换和流化音频和视频的完整解决方案 ...

  9. 由pushViewController说起可能出线的各种死法

    做苹果开发或者果粉对导航条这个东西应该都不陌生,这咚咚在小小的屏幕上通过一个简单的View的队列管理来做到手机界面的有条理管理,但是开发过程程序员可能碰到各种死法,下面分享一二.            ...

  10. 用Eclipse给安卓应用进行签名

    Eclipse功能强大,用它来给应用进行签名也十分简单.下面是进行签名的步骤