怎么在c++builder中执行dos命令

时间:2022-09-02 22:39:26
怎么给只有命令行的程序加个界面?

比如要执行"dir"命令,然后把打印出来的信息显示到Memo或Richedit里面.

10 个解决方案

#1


^-^
用定向先导到文件,再把文件显示在TMemo或TRich中
如:
  dir c: >c:\b.txt

 ------
  rich->LoadFromFile("c:\b.txt");

#2


搜索“管道”

#3


system("dir >> a.txt");
Memo1->Lines->LoadFromFile("a.txt");

#4


管道是比较好的办法,没有命令行窗口一闪而过

#5


引用 2 楼 ccrun 的回复:
搜索“管道”


//---------------------------------------------------------------------------   
String   __fastcall   TForm1::ExecuteApp(String   sCmdline)   
{   
        PROCESS_INFORMATION   proc   =   {0};   
        long   ret,k=1;   
        bool   bret;   
        STARTUPINFO   start   =   {0};   
        SECURITY_ATTRIBUTES   sa   =   {0};   
        HANDLE   hReadPipe   ;   
        HANDLE   hWritePipe;   
        String   sOutput;         
        String   sBuffer;   
        unsigned   long   lngBytesRead;   
        char   cBuffer[257];   
        sa.nLength   =   sizeof(sa);   
        sa.lpSecurityDescriptor=0;   
        sa.bInheritHandle   =   TRUE;   
        bret   =::CreatePipe(&hReadPipe,   &hWritePipe,&sa,   0);   
        if   (!bret)   
        {   
                sOutput= "CreatePipe   failed.   Error:   "   +   String(GetLastError());   
                Memo1-> Lines-> Add(sOutput);   
                return   sOutput;   
        }   
        start.cb   =   sizeof(STARTUPINFOA);   
        start.dwFlags   =   STARTF_USESTDHANDLES   |   STARTF_USESHOWWINDOW;   
        start.hStdOutput   =   hWritePipe;   
        start.hStdError   =   hWritePipe;   
        start.wShowWindow   =   SW_HIDE;   
        sBuffer   =   sCmdline;   
        ret   =::CreateProcess(0,   sBuffer.c_str(),   &sa,   &sa,   TRUE,   NORMAL_PRIORITY_CLASS,   0,   0,   &start,   &proc);   
        if   (ret   ==   0)   
        {   
                sOutput= "Bad   command   or   filename ";   
                Memo1-> Lines-> Add(sOutput);   
                return   sOutput;   
        }   
        ::CloseHandle(hWritePipe);   
        do   
        {   
                memset(cBuffer, '\0 ',sizeof(cBuffer));   
                ret   =   ::ReadFile(hReadPipe,   &cBuffer,   256,   &lngBytesRead,   0);   
                sBuffer=StrPas(cBuffer);   
                sOutput   =   sOutput   +   sBuffer;   
                Memo1-> Text=Memo1-> Text+sBuffer;   
                Application-> ProcessMessages();   

        }   while   (ret   !=   0   );   
        ::CloseHandle(proc.hProcess);   
        ::CloseHandle(proc.hThread);   
        ::CloseHandle(hReadPipe);   
        return   sOutput;   
}   
//---------------------------------------------------------------------------   
void   __fastcall   TForm1::Button1Click(TObject   *Sender)   
{         
        ExecuteApp( "Ping   www.chinabcb.com ");   
}   
//---------------------------------------------------------------------------   
  


下面是运行结果:   

引用:   
Pinging   www.chinabcb.com   [218.22.205.4]   with   32   bytes   of   data:   

Reply   from   218.22.205.4:   bytes=32   time=60ms   TTL=115   
Reply   from   218.22.205.4:   bytes=32   time=50ms   TTL=115   
Reply   from   218.22.205.4:   bytes=32   time=140ms   TTL=115   
Reply   from   218.22.205.4:   bytes=32   time=81ms   TTL=115   

Ping   statistics   for   218.22.205.4:   

Packets:   Sent   =   4,   Received   =   4,   Lost   =   0   (0%   loss),   
Approximate   round   trip   times   in   milli-seconds:   
Minimum   =   50ms,   Maximum   =   140ms,   Average   =   82ms 


这种方法在c++builder 2010下有乱码.

#6



void __fastcall TForm1::Button2Click(TObject *Sender)
{
  SECURITY_ATTRIBUTES sa;
  HANDLE hRead,hWrite;

  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE;
  if (!CreatePipe(&hRead,&hWrite,&sa,0))
  {
    ShowMessage("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 c:"
        ,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
  {
    ShowMessage("Error on CreateProcess()");
    return;
  }
  CloseHandle(hWrite);

  char buffer[4096] = {0};
  DWORD bytesRead;
  while (true)
  {
    if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL)
      break;
    Memo1->Lines->Add(buffer);
  }
  ::CloseHandle(pi.hProcess);
  ::CloseHandle(pi.hThread);
  ::CloseHandle(hRead);
}

#7


从哪抄来的代码?

sBuffer=StrPas(cBuffer); 
改成:
sBuffer=String(cBuffer);
就行了

#8


就在论坛上搜索的,我试试

#9


引用 7 楼 ccrun 的回复:
从哪抄来的代码?

sBuffer=StrPas(cBuffer); 
改成:
sBuffer=String(cBuffer);
就行了


还是有乱码,另外就是在MEMO中显示的位置不在最左边,是不是换行码不起作用?

如果改成这样
Memo1->Text = sOutput ;
  return sOutput;

是没乱码了,但显示的位置还是和上面一样不对.

#10


该回复于2010-11-02 10:20:02被版主删除

#1


^-^
用定向先导到文件,再把文件显示在TMemo或TRich中
如:
  dir c: >c:\b.txt

 ------
  rich->LoadFromFile("c:\b.txt");

#2


搜索“管道”

#3


system("dir >> a.txt");
Memo1->Lines->LoadFromFile("a.txt");

#4


管道是比较好的办法,没有命令行窗口一闪而过

#5


引用 2 楼 ccrun 的回复:
搜索“管道”


//---------------------------------------------------------------------------   
String   __fastcall   TForm1::ExecuteApp(String   sCmdline)   
{   
        PROCESS_INFORMATION   proc   =   {0};   
        long   ret,k=1;   
        bool   bret;   
        STARTUPINFO   start   =   {0};   
        SECURITY_ATTRIBUTES   sa   =   {0};   
        HANDLE   hReadPipe   ;   
        HANDLE   hWritePipe;   
        String   sOutput;         
        String   sBuffer;   
        unsigned   long   lngBytesRead;   
        char   cBuffer[257];   
        sa.nLength   =   sizeof(sa);   
        sa.lpSecurityDescriptor=0;   
        sa.bInheritHandle   =   TRUE;   
        bret   =::CreatePipe(&hReadPipe,   &hWritePipe,&sa,   0);   
        if   (!bret)   
        {   
                sOutput= "CreatePipe   failed.   Error:   "   +   String(GetLastError());   
                Memo1-> Lines-> Add(sOutput);   
                return   sOutput;   
        }   
        start.cb   =   sizeof(STARTUPINFOA);   
        start.dwFlags   =   STARTF_USESTDHANDLES   |   STARTF_USESHOWWINDOW;   
        start.hStdOutput   =   hWritePipe;   
        start.hStdError   =   hWritePipe;   
        start.wShowWindow   =   SW_HIDE;   
        sBuffer   =   sCmdline;   
        ret   =::CreateProcess(0,   sBuffer.c_str(),   &sa,   &sa,   TRUE,   NORMAL_PRIORITY_CLASS,   0,   0,   &start,   &proc);   
        if   (ret   ==   0)   
        {   
                sOutput= "Bad   command   or   filename ";   
                Memo1-> Lines-> Add(sOutput);   
                return   sOutput;   
        }   
        ::CloseHandle(hWritePipe);   
        do   
        {   
                memset(cBuffer, '\0 ',sizeof(cBuffer));   
                ret   =   ::ReadFile(hReadPipe,   &cBuffer,   256,   &lngBytesRead,   0);   
                sBuffer=StrPas(cBuffer);   
                sOutput   =   sOutput   +   sBuffer;   
                Memo1-> Text=Memo1-> Text+sBuffer;   
                Application-> ProcessMessages();   

        }   while   (ret   !=   0   );   
        ::CloseHandle(proc.hProcess);   
        ::CloseHandle(proc.hThread);   
        ::CloseHandle(hReadPipe);   
        return   sOutput;   
}   
//---------------------------------------------------------------------------   
void   __fastcall   TForm1::Button1Click(TObject   *Sender)   
{         
        ExecuteApp( "Ping   www.chinabcb.com ");   
}   
//---------------------------------------------------------------------------   
  


下面是运行结果:   

引用:   
Pinging   www.chinabcb.com   [218.22.205.4]   with   32   bytes   of   data:   

Reply   from   218.22.205.4:   bytes=32   time=60ms   TTL=115   
Reply   from   218.22.205.4:   bytes=32   time=50ms   TTL=115   
Reply   from   218.22.205.4:   bytes=32   time=140ms   TTL=115   
Reply   from   218.22.205.4:   bytes=32   time=81ms   TTL=115   

Ping   statistics   for   218.22.205.4:   

Packets:   Sent   =   4,   Received   =   4,   Lost   =   0   (0%   loss),   
Approximate   round   trip   times   in   milli-seconds:   
Minimum   =   50ms,   Maximum   =   140ms,   Average   =   82ms 


这种方法在c++builder 2010下有乱码.

#6



void __fastcall TForm1::Button2Click(TObject *Sender)
{
  SECURITY_ATTRIBUTES sa;
  HANDLE hRead,hWrite;

  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE;
  if (!CreatePipe(&hRead,&hWrite,&sa,0))
  {
    ShowMessage("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 c:"
        ,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
  {
    ShowMessage("Error on CreateProcess()");
    return;
  }
  CloseHandle(hWrite);

  char buffer[4096] = {0};
  DWORD bytesRead;
  while (true)
  {
    if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL)
      break;
    Memo1->Lines->Add(buffer);
  }
  ::CloseHandle(pi.hProcess);
  ::CloseHandle(pi.hThread);
  ::CloseHandle(hRead);
}

#7


从哪抄来的代码?

sBuffer=StrPas(cBuffer); 
改成:
sBuffer=String(cBuffer);
就行了

#8


就在论坛上搜索的,我试试

#9


引用 7 楼 ccrun 的回复:
从哪抄来的代码?

sBuffer=StrPas(cBuffer); 
改成:
sBuffer=String(cBuffer);
就行了


还是有乱码,另外就是在MEMO中显示的位置不在最左边,是不是换行码不起作用?

如果改成这样
Memo1->Text = sOutput ;
  return sOutput;

是没乱码了,但显示的位置还是和上面一样不对.

#10


该回复于2010-11-02 10:20:02被版主删除