Windows Delphi:创建和读取文本文件会导致I/O 32错误。这应该通过睡眠来预防吗?

Windows Delphi:创建和读取文本文件会导致I/O 32错误。这应该通过睡眠来预防吗?,windows,delphi,sleep,Windows,Delphi,Sleep,我目前正在开发一个程序,需要能够报告Windows是否已激活 function TSoftwareReport.getLicenceInfo : String; var Activated : String; LicenceFile : TextFile; begin // redirect command output to txt file ShellExecute(0,nil,'cmd.exe', '/C cscript %windir%\system32\slmgr.vb

我目前正在开发一个程序,需要能够报告Windows是否已激活

function TSoftwareReport.getLicenceInfo : String;
var
  Activated : String;
  LicenceFile : TextFile;
begin
  // redirect command output to txt file
  ShellExecute(0,nil,'cmd.exe', '/C cscript %windir%\system32\slmgr.vbs/xpr > C:\Activated.txt', nil, SW_HIDE);
  //Read the file
  Sleep(1000);
  AssignFile(LicenceFile, 'C:\Activated.txt');
  Reset(LicenceFile);
  while not Eof(LicenceFile) do
  begin
    ReadLn(LicenceFile,Activated);
    if AnsiContainsText(Activated, 'Permanently') then
    begin
      Activated := 'Permanent';
      Break;
    end;
  end;
  //cleanup file
  CloseFile(LicenceFile);
  DelDir('C:\Activated.txt');
  Result := Activated;
end;
目前,我正在使用ShellExecute并将输出重定向到一个文本文件,然后我想读取该文件,以确定Windows是否已激活

function TSoftwareReport.getLicenceInfo : String;
var
  Activated : String;
  LicenceFile : TextFile;
begin
  // redirect command output to txt file
  ShellExecute(0,nil,'cmd.exe', '/C cscript %windir%\system32\slmgr.vbs/xpr > C:\Activated.txt', nil, SW_HIDE);
  //Read the file
  Sleep(1000);
  AssignFile(LicenceFile, 'C:\Activated.txt');
  Reset(LicenceFile);
  while not Eof(LicenceFile) do
  begin
    ReadLn(LicenceFile,Activated);
    if AnsiContainsText(Activated, 'Permanently') then
    begin
      Activated := 'Permanent';
      Break;
    end;
  end;
  //cleanup file
  CloseFile(LicenceFile);
  DelDir('C:\Activated.txt');
  Result := Activated;
end;
我遇到的问题是,当我执行ShellExecute行,然后执行AssignFile行时,我得到一个I/O32错误。我怀疑这是由于ShellExecute在我尝试使用“AssignFile”访问该文件之前没有关闭该文件。这就是为什么我现在有了Sleep()行。问题是我不知道我应该睡多久,因为不同机器的性能会有所不同

我尝试编写代码,尝试运行AssignFile行,如果失败,则使用sleep()并重试,但现在我故意抛出异常。这整件事让人觉得很无聊,写得很糟糕。我已经为不得不将输出从shellexecute重定向到文本文件而感到难过

所以问题是,我应该使用睡眠吗?如果是,我该如何决定睡眠时间?我应该使用另一种方法吗

我应该使用睡眠吗

没有

我应该使用另一种方法吗

对。使用等待函数阻止,直到您创建的进程终止。然后读取输出文件

有几个选项会影响您的设计选择

为了等待,您需要获得一个进程句柄。您可以使用
ShellExecuteEx
CreateProcess
来实现这一点。但不能使用
ShellExecute

如果您希望重定向输出,但不想自己编写重定向代码,则需要继续使用
cmd.exe
,并让它执行重定向。或者,您可以使用
CreateProcess
并提供文件句柄或管道句柄作为新的进程标准句柄

如果我是你,我会避免创建一个只用于瞬态输出的文件。这就是制造管道的目的。创建一个管道并将其写入端作为新进程的stdout馈送到新进程。从管道的读取端读取内容。这样可以避免将文件喷入文件系统。更重要的是,它允许您避免产生您不需要的
cmd.exe
进程

最后要指出的一点是,在调用
ShellExecute
时不检查错误。诚然,
ShellExecute
不能很好地报告错误,但您必须学会在调用API函数时检查错误。如果功能失败,而您没有检查错误,您怎么能期望诊断出哪里出了问题