这段代码怎么回事?(50分)

  • 主题发起人 主题发起人 zanpen2001
  • 开始时间 开始时间
Z

zanpen2001

Unregistered / Unconfirmed
GUEST, unregistred user!

各位帮我看看下面的代码,跟踪的时候一切正常,但正常执行时Aresult的值却不是我想要的:
procedure sql_Service_status(service_name:string;var Aresult:string);
var
tmp_net:pchar;
Sreadln:string;
f:textfile;
sb,ss:string;
begin
Aresult :='0';
getusername_computername;
sb := 'Sybase BCKServer _ ' + uppercase(cp_name) + '_BS'
ss := 'Sybase SQLServer _ ' + uppercase(cp_name)
if fileexists('temp.txt') then deletefile('temp.txt');
tmp_net := 'cmd /c net start > temp.txt';

WinExec(tmp_net,sw_hide);
if not fileexists('temp.txt') then
begin
Aresult:='9';
exit;
end;
try
Assign(f,'temp.txt');
reset(f);
while not eof(f) do
begin
Readln(f,sreadln);
sreadln := trim(sreadln);
if strcomp(pchar(uppercase(ss)),pchar(uppercase(sreadln))) = 0 then
begin
Aresult := '1';

break;
end;
if strcomp(pchar(uppercase(sb)),pchar(uppercase(sreadln))) = 0 then
begin
Aresult :='2';
break;
end;
end;
CloseFile(f);
except
raise;
end;
end;
 
WinExec(tmp_net,sw_hide);是异步执行的。所以蹦叉。
 
看一下下面的,希望有用。
此函数能够实现功能,但是如果控制台没有相应,则程序死掉。使用时需要进行修改,同时此函数经过改
动能够实现向Dos控制台发送消息的功能。

function GetDosOutput(const CommandLine: string): string;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of Char;
BytesRead: Cardinal;
WorkDir, Line: string;
begin
Application.ProcessMessages;
with SA do
begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
// create pipe for standard output redirection
CreatePipe(StdOutPipeRead, // read handle
StdOutPipeWrite, // write handle
@SA, // security attributes
0 // number of bytes reserved for pipe - 0 default
);
try
// Make child process use StdOutPipeWrite as standard out,
// and make sure it does not show on screen.
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE)
// don't redirect std input
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;

// launch the command line compiler
WorkDir := ExtractFilePath(CommandLine);
WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil,
PChar(WorkDir), SI, PI);

// Now that the handle has been inherited, close write to be safe.
// We don't want to read or write to it accidentally.
CloseHandle(StdOutPipeWrite);
// if process could be created then handle its output
if not WasOK then
raise Exception.Create('Could not execute command line!')
else
try
// get all output until dos app finishes
Line := '';
repeat
// read block of characters (might contain carriage returns and line feeds)
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);

// has anything been read?
if BytesRead > 0 then
begin
// finish buffer to PChar
Buffer[BytesRead] := #0;
// combine the buffer with the rest of the last run
Line := Line + Buffer;
end;
until not WasOK or (BytesRead = 0);
// wait for console app to finish (should be already at this point)
WaitForSingleObject(PI.hProcess, INFINITE);
finally
// Close all remaining handles
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
result := Line;
CloseHandle(StdOutPipeRead);
end;
end;
 
可是我跟踪的时候一切正常啊!您能说得再细点吗?谢了
 
执行下面的,你看看,是不是两个计算机都蹦出来了,你希望的是一个执行完,然后下一个才执行。
就是顺序执行,可是很遗憾,Winexec不是,它没有执行完就将程序的控制权返回了,所以程序可以继续
执行下去,因此导致你判断是否存在文件的时候出错,因为此时那个程序还没有执行完呢。

procedure TForm1.Button1Click(Sender: TObject);
begin
WinExec('C:/Windows/Calc.exe',SW_Normal);
WinExec('C:/Windows/Calc.exe',SW_Normal);
end;
 
老兄,上面的代码我有,其实我只是想知道那个服务启动没有,不想搞得那么复杂,
temp.txt文件其实已经建好了,只是查不到,或者根本进入不了while not eof(f),不知道
怎么回事。。。。。愁死了。。。

简单地说,就是想在这个文件里查字符串,如果找到了,Aresult 就赋值,否则返回'0'
 
所以我给你上面的取得控制台信息的代码,你可以等它执行完毕,将文件控制权交给操作系统以后再
对它进行读取,因为你读取的时候,文件还在使用呢。
你必须等它正常关闭,然后才能进行检索,否则,不关结果是否正确,都应该算错误!
 
明白了,其实只要在WinExec(tmp_net,sw_hide);后面加个sleep(500)就行了,OK!

其实更好的方法是用createprocess然后等待其执行完成。。。。
 
你说对了。[:D][:)]
 
后退
顶部