如何在WIN2000中执行DOS程序,并把结果用管道得到 使用API函数:WinExec来运行你的相关DOS命令。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 WinExec是老版本的Win32函数。新的应该用ShellExecute吧。 //呵呵,你运气好呀,我前几天刚调好这个98和2000都能正常执行的东西unit Unit2;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; function RunDOS(const CommandLine: String): String; implementationfunction RunDos(const CommandLine: String): String;var sa:TSecurityAttributes; sd: SECURITY_DESCRIPTOR; lpsa: PSecurityAttributes; hReadPipe,hWritePipe :THandle; si: TStartupInfo; pi: TProcessInformation ; dest: array [0..4095] of char; BytesRead: Dword; function IsWindowsNT: Boolean; var osv: OSVERSIONINFO ; begin; osv.dwOSVersionInfoSize := sizeof(osv); GetVersionEx(osv); if (osv.dwPlatformId = VER_PLATFORM_WIN32_NT) then Result :=TRUE ELSE rESULT:=False; end;begin Result:='调用失败'; // If NT do security stuff lpsa := nil; if (IsWindowsNT) then begin InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(@sd, true, nil, false); sa.nLength := sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle := true; sa.lpSecurityDescriptor := @sd; lpsa := @sa; end; // Create the Pipe and get r/w handles assert(CreatePipe(hReadPipe, hWritePipe, lpsa, 2500000)); // initialize STARTUPINFO struct FillChar(si,SizeOf(TStartupInfo),0); si.cb := sizeof(TStartupInfo); si.dwFlags := STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES; si.wShowWindow := SW_HIDE; si.hStdOutput := hWritePipe; si.hStdError := hWritePipe; CreateProcess(nil, PChar(CommandLine), nil,//security nil,// security TRUE,//inherits handles 0, nil, nil, si, pi); CloseHandle(pi.hThread); WaitForSingleObject(pi.hProcess, 90000); if ReadFile(hReadPipe,dest,sizeof(dest),BytesRead,nil) then Result:=Copy(String(dest),1,BytesRead); // Process cleanup CloseHandle(hReadPipe); CloseHandle(hWritePipe); CloseHandle(pi.hProcess);end;end. 谢谢RadAsm(win32asm),可是你的程序在我这儿还是死机!我各种方法都试过了,都不行。我的OS是Windows 2000(Build 2195)Delphi EnterpriseVersion 5.0 (Build 5.62)RadAsm(win32asm) 你能抽空帮我试试我的程序吗?看看错在哪儿?这程序几乎和你的程序一样!procedure TForm1.BtnOKClick(Sender: TObject);var hh:THandle; fn,dr:array[0..79] of Char; si:TStartupInfo; pi:TProcessInformation; ss:boolean; lsa:TSecurityAttributes; lsd:TSecurityDescriptor; hReadP,hWriteP:THandle; inS:THandleStream; sRet:TStrings; ExitCode,LI:DWORD; lpOverlap:TOverlapped; temp:array[0..4095] of char; CommandLine : string;procedure CheckResult(b: Boolean);begin if not b then Raise Exception.Create(SysErrorMessage(GetLastError));end;begin {StrPCopy(fn,FileListBox1.FileName);} StrPCopy(dr,FileListBox1.Directory); StrPCopy(fn,Edit1.Text); CommandLine := dr+'\'+fn+' '+Edit2.Text; InitializeSecurityDescriptor(@lsd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(@lsd, true, nil, false); //Result := ''; FillChar(lsa,sizeof(lsa),0); lsa.nLength:=sizeof(TSecurityAttributes); { ss := InitializeSecurityDescriptor( @lsd, SECURITY_DESCRIPTOR_REVISION ); if ss then LI := 0; } lsa.lpSecurityDescriptor:=@lsd; lsa.bInheritHandle:=True; ss:=CreatePipe(hReadP,hWriteP,@lsa,20000); CheckResult(ss); { DuplicateHandle(GetCurrentProcess(), hReadPipe, GetCurrentProcess(), nil,0,False,0); DuplicateHandle(GetCurrentProcess(), hWP1, GetCurrentProcess(), @hWP2,0,True,0); } FillChar(si,SizeOf(si),0); si.cb:=sizeof(TStartupInfo); { si.lpReserved:=nil; si.lpTitle:=nil; si.lpDesktop:=nil; si.dwX:=0; si.dwY:=0; si.dwXSize:=00; si.dwYSize:=00; } si.dwFlags:=STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; //.hStdInput:= GetStdHandle(STD_INPUT_HANDLE); //.hStdOutput:= GetStdHandle(STD_OUTPUT_HANDLE); //.tdError:= GetStdHandle(STD_OUTPUT_HANDLE); si.hStdOutput:= hWriteP; si.hStdError:= hWriteP; //si.lpReserved2:=nil; //si.cbReserved2:=0; si.wShowWindow:=SW_HIDE; ss:=CreateProcess(nil, PChar(CommandLine), nil,nil,True, //CREATE_NEW_CONSOLE, 0,//CREATE_SEPARATE_WOW_VDM, nil,nil, si, pi); CheckResult(ss); CloseHandle(pi.hThread); WaitForSingleObject(pi.hProcess, 90000); { repeat LI :=0 ; ss := PeekNamedPipe(hReadP,@temp,1,@LI,nil,Nil); CheckResult(ss); if LI >0 then begin ss := ReadFile(hReadP,temp,2000,LI,nil); CheckResult(ss); Memo1.Lines.add(temp); end else begin if WaitForSingleObject(pi.hProcess,0) = WAIT_OBJECT_0 then break; sleep(256); //GetExitCodeProcess(pi.hProcess,ExitCode); end; until False; } { inS := THandleStream.Create(hReadP); if inS.Size>0 then begin sRet := TStringList.Create; sRet.LoadFromStream(inS); Memo1.Lines.add(sRet.Text); sRet.Free; end; inS.Free; } Memo1.Clear; FillChar(temp,sizeof(temp),0); //ss := PeekNamedPipe(hReadP,@temp,sizeof(temp),@LI,nil,Nil); // 总是在这儿死机!!! ReadFile(hReadP,temp,sizeof(temp),LI,nil); //if ss then Memo1.Lines.add(temp); CloseHandle(hReadP); CloseHandle(pi.hProcess); CloseHandle(hWriteP);end; 死机?不该呀,我在好几台不同的机器上测试过了的。我的OS和Delphi版本和你的是一样的.另外还在98和ME上通过.那个函数是从BCB的DEMO里面改过来的不应该有什么问题你看看你程序的其它部分有没有什么问题呢 的确死机!当执行到ReadFile这句时,既不出错也不退出,就停在这儿。上面的PeekNamedPipe倒是能退出,ss也为真,可是LI总是为0。这个程序我在Delphi4上调试,也是同样的结果。其它地方没有程序,只是处理按钮,输入程序字串,命令行参数等。RadAsm(win32asm)老兄将你的Project全发来?多谢了。 一是不能执行DOS内部命令,二是要给出正确的路径由command.com解释的内部命令我想不能这样来执行如果你还需要,我作个简单的发给你吧,我的那个Project太大了 问题是我的程序在WIN98下执行的是正确的啊!就是在WIN2000下,ReadFile死在那儿不退出。能不能把RUNDOS的可执行程序EMAIL过来? RadAsm(win32asm) 你的代码我试验过了, 但当我用他调用Bc++3.1编译器程序Bcc.exe编译程序时候却出现许多未关闭的WinOldAp程序 查最小日期和时间 三层的入门问题 delphi 宏定义 如何设置主从关系? 下周手术,散分保平安。请斑竹大人手下留情,在此谢过 数据库备份问题??急用呀?? 急、急、急!如何在主窗体中SendMessage后,在多子窗体中获取该消息! dbgrid中文本的获得? ActiveX问题 要多少分,请开口!!(MAX=8410):如何在发送正文为HTML格式的邮件(同时带附件)!!! 请问管理信息系统怎么做啊 请问那位仁兄有关于压缩算法的Delphi中文资料?[小胡]
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
function RunDOS(const CommandLine: String): String;
implementationfunction RunDos(const CommandLine: String): String;
var
sa:TSecurityAttributes;
sd: SECURITY_DESCRIPTOR;
lpsa: PSecurityAttributes;
hReadPipe,hWritePipe :THandle;
si: TStartupInfo;
pi: TProcessInformation ;
dest: array [0..4095] of char;
BytesRead: Dword;
function IsWindowsNT: Boolean;
var
osv: OSVERSIONINFO ;
begin;
osv.dwOSVersionInfoSize := sizeof(osv);
GetVersionEx(osv);
if (osv.dwPlatformId = VER_PLATFORM_WIN32_NT) then
Result :=TRUE ELSE rESULT:=False;
end;
begin
Result:='调用失败';
// If NT do security stuff
lpsa := nil;
if (IsWindowsNT) then
begin
InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(@sd, true, nil, false);
sa.nLength := sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle := true;
sa.lpSecurityDescriptor := @sd;
lpsa := @sa;
end; // Create the Pipe and get r/w handles
assert(CreatePipe(hReadPipe,
hWritePipe,
lpsa,
2500000));
// initialize STARTUPINFO struct
FillChar(si,SizeOf(TStartupInfo),0);
si.cb := sizeof(TStartupInfo);
si.dwFlags := STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES;
si.wShowWindow := SW_HIDE;
si.hStdOutput := hWritePipe;
si.hStdError := hWritePipe; CreateProcess(nil,
PChar(CommandLine),
nil,//security
nil,// security
TRUE,//inherits handles
0,
nil,
nil,
si,
pi); CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, 90000); if ReadFile(hReadPipe,dest,sizeof(dest),BytesRead,nil) then
Result:=Copy(String(dest),1,BytesRead); // Process cleanup
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
CloseHandle(pi.hProcess);
end;end.
我各种方法都试过了,都不行。
我的OS是Windows 2000(Build 2195)
Delphi Enterprise
Version 5.0 (Build 5.62)RadAsm(win32asm) 你能抽空帮我试试我的程序吗?
看看错在哪儿?这程序几乎和你的程序一样!
procedure TForm1.BtnOKClick(Sender: TObject);
var
hh:THandle;
fn,dr:array[0..79] of Char;
si:TStartupInfo;
pi:TProcessInformation;
ss:boolean;
lsa:TSecurityAttributes;
lsd:TSecurityDescriptor;
hReadP,hWriteP:THandle;
inS:THandleStream;
sRet:TStrings;
ExitCode,LI:DWORD;
lpOverlap:TOverlapped;
temp:array[0..4095] of char;
CommandLine : string;procedure CheckResult(b: Boolean);
begin
if not b then
Raise Exception.Create(SysErrorMessage(GetLastError));
end;begin
{StrPCopy(fn,FileListBox1.FileName);}
StrPCopy(dr,FileListBox1.Directory);
StrPCopy(fn,Edit1.Text);
CommandLine := dr+'\'+fn+' '+Edit2.Text; InitializeSecurityDescriptor(@lsd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(@lsd, true, nil, false);
//Result := '';
FillChar(lsa,sizeof(lsa),0);
lsa.nLength:=sizeof(TSecurityAttributes);
{
ss := InitializeSecurityDescriptor(
@lsd, SECURITY_DESCRIPTOR_REVISION );
if ss then
LI := 0;
}
lsa.lpSecurityDescriptor:=@lsd;
lsa.bInheritHandle:=True; ss:=CreatePipe(hReadP,hWriteP,@lsa,20000);
CheckResult(ss);
{
DuplicateHandle(GetCurrentProcess(),
hReadPipe,
GetCurrentProcess(),
nil,0,False,0); DuplicateHandle(GetCurrentProcess(),
hWP1,
GetCurrentProcess(),
@hWP2,0,True,0);
}
FillChar(si,SizeOf(si),0);
si.cb:=sizeof(TStartupInfo);
{
si.lpReserved:=nil;
si.lpTitle:=nil;
si.lpDesktop:=nil;
si.dwX:=0;
si.dwY:=0;
si.dwXSize:=00;
si.dwYSize:=00;
}
si.dwFlags:=STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
//.hStdInput:= GetStdHandle(STD_INPUT_HANDLE);
//.hStdOutput:= GetStdHandle(STD_OUTPUT_HANDLE);
//.tdError:= GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdOutput:= hWriteP;
si.hStdError:= hWriteP;
//si.lpReserved2:=nil;
//si.cbReserved2:=0;
si.wShowWindow:=SW_HIDE; ss:=CreateProcess(nil,
PChar(CommandLine),
nil,nil,True,
//CREATE_NEW_CONSOLE,
0,//CREATE_SEPARATE_WOW_VDM,
nil,nil,
si,
pi); CheckResult(ss);
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, 90000);
{
repeat
LI :=0 ;
ss := PeekNamedPipe(hReadP,@temp,1,@LI,nil,Nil);
CheckResult(ss);
if LI >0 then
begin
ss := ReadFile(hReadP,temp,2000,LI,nil);
CheckResult(ss);
Memo1.Lines.add(temp); end else
begin
if WaitForSingleObject(pi.hProcess,0) = WAIT_OBJECT_0
then break;
sleep(256);
//GetExitCodeProcess(pi.hProcess,ExitCode);
end;
until False;
}
{
inS := THandleStream.Create(hReadP);
if inS.Size>0 then
begin
sRet := TStringList.Create;
sRet.LoadFromStream(inS);
Memo1.Lines.add(sRet.Text);
sRet.Free;
end;
inS.Free;
} Memo1.Clear;
FillChar(temp,sizeof(temp),0);
//ss := PeekNamedPipe(hReadP,@temp,sizeof(temp),@LI,nil,Nil);
// 总是在这儿死机!!!
ReadFile(hReadP,temp,sizeof(temp),LI,nil);
//if ss then
Memo1.Lines.add(temp); CloseHandle(hReadP);
CloseHandle(pi.hProcess);
CloseHandle(hWriteP);end;
版本和你的是一样的.另外还在98和ME上通过.
那个函数是从BCB的DEMO里面改过来的不应该有什么问题
你看看你程序的其它部分有没有什么问题呢
当执行到ReadFile这句时,既不出错也不退出,就停在这儿。
上面的PeekNamedPipe倒是能退出,ss也为真,可是LI总是为0。
这个程序我在Delphi4上调试,也是同样的结果。
其它地方没有程序,只是处理按钮,输入程序字串,命令行参数等。
RadAsm(win32asm)老兄将你的Project全发来?
多谢了。
由command.com解释的内部命令我想不能这样来执行
如果你还需要,我作个简单的发给你吧,我的那个Project太大了
就是在WIN2000下,ReadFile死在那儿不退出。
能不能把RUNDOS的可执行程序EMAIL过来?
你的代码我试验过了, 但当我用他
调用Bc++3.1编译器程序Bcc.exe编译程序
时候却出现许多未关闭的WinOldAp程序