在线程中使用此代码有什么问题吗?(DELPHI)

Ker*_*mia 4 delphi multithreading indy shellexecute

我在一个线程中使用此代码(通过Indy Onexecute事件).有什么问题吗 ?

function TFrmMain.ShellExecute_AndWait(FileName, Params: string): bool;
var
  exInfo: TShellExecuteInfo;
  Ph: DWORD;
begin
  FillChar(exInfo, SizeOf(exInfo), 0);
  with exInfo do
  begin
    cbSize := SizeOf(exInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
    Wnd := GetActiveWindow();
    exInfo.lpVerb := 'open';
    exInfo.lpParameters := PChar(Params);
    lpFile := PChar(FileName);
    nShow := SW_NORMAL;
  end;
  if ShellExecuteEx(@exInfo) then
    Ph := exInfo.hProcess
  else
  begin
    Result := true;
    exit;
  end;
  while WaitForSingleObject(exInfo.hProcess, 50) <> WAIT_OBJECT_0 do
  begin

  end;
  CloseHandle(Ph);
  Result := true;
end;
Run Code Online (Sandbox Code Playgroud)

Rob*_*edy 8

MSDN有这样的建议:

由于ShellExecuteEx可以将执行委托给使用组件对象模型(COM)激活的Shell扩展(数据源,上下文菜单处理程序,动词实现),因此应在调用ShellExecuteEx之前初始化COM.某些Shell扩展需要COM单线程单元(STA)类型.在这种情况下,COM应该初始化,如下所示:

CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
Run Code Online (Sandbox Code Playgroud)

有些情况下ShellExecuteEx不使用这些类型的Shell扩展之一,并且这些实例根本不需要初始化COM.尽管如此,在使用此功能之前始终初始化COM是一种好习惯.

(在Delphi中,您当然nil要用第一个参数替换并or用于按位操作.)

雷蒙德陈最近写了关于弄错的后果.具体示例是该函数可能会失败并显示Error_Access_Denied错误代码.

这是我在代码中看到的唯一潜在的多线程问题.下面是我阅读你的代码时发生的更多事情,尽管它们与多线程无关(甚至与Indy无关).


你有一种特殊的方式等待程序停止运行.你一次反复等待50毫秒,但如果这个过程还没有完成,你什么都不做,只能再等一下.通过指定Infinite超时来更准确地描述您的意图.


该函数始终返回True.如果没有有用的返回值,那么你应该把它作为一个程序,这样根本就没有返回值.不要将呼叫者与无用的信息混淆.如果您要将其保留为函数,则使用Delphi本机类型Boolean而不是Windows兼容性类型Bool作为返回类型.


我对服务器在收到网络消息时执行用户交互程序的想法有点警惕.


请注意,MSDN表示您可能无法获得进程句柄.有些情况下ShellExecuteEx可以在不创建新流程的情况下为您的请求提供服务,因此您无需等待.

用户可能最终会在一段时间内使用该程序,并且您的服务器将一直处于等待状态.我想知道它是否真的需要等待.客户端是否也在等待服务器的响应?