【问题标题】:Is there any problem to using this code in a Thread ? (Delphi)在 Thread 中使用此代码有什么问题吗? (德尔福)
【发布时间】:2011-05-17 15:54:58
【问题描述】:

我在线程中使用此代码(通过 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;

【问题讨论】:

    标签: multithreading delphi indy shellexecute


    【解决方案1】:

    MSDN 有这个建议:

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

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
    

    在某些情况下,ShellExecuteEx 不使用这些类型的 Shell 扩展之一,并且这些实例根本不需要初始化 COM。尽管如此,在使用此函数之前始终初始化 COM 是一种很好的做法。

    (在 Delphi 中,您当然会将第一个参数替换为 nil 并使用 or 进行按位运算。)

    Raymond Chen 最近写了一篇关于the consequences of getting this wrong 的文章。具体的例子是函数可能会失败并出现Error_Access_Denied 错误代码。

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


    您有一种特殊的方式来等待程序停止运行。您一次重复等待 50 毫秒,但如果该过程尚未完成,您只需要再次等待即可。通过指定Infinite 来更准确地描述您的意图。


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


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


    请注意,当 MSDN 说您可能无法获得进程句柄时。在某些情况下,ShellExecuteEx 可以在不创建新进程的情况下为您的请求提供服务,因此您无需等待。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      • 1970-01-01
      • 2018-03-05
      • 2020-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多