【问题标题】:ShellExecuteEx and Coinitialize in VCL threadVCL 线程中的 ShellExecuteEx 和 Coinitialize
【发布时间】:2013-11-14 17:53:06
【问题描述】:

我是否需要在 Delphi 的 main/VCL 线程中调用 Coinitialize 在使用ShellExecuteEx之前?

对于线程,是的,但是对于 VCL 线程?

【问题讨论】:

    标签: delphi delphi-7


    【解决方案1】:

    Windows 窗体应用程序无需致电CoInitialize。 这是在主线程中为您完成的。 更具体的TApplication.CreateForms.Pas

    ...
    if not IsLibrary then
     FNeedToUninitialize := Succeeded(OleInitialize(nil));
    ...
    

    【讨论】:

    • Application.Initialize 期间不是在 InitProc 中完成初始化吗?
    • @DavidHeffernan:这是我可以在源启动代码中找到的唯一与 COM 相关的初始化(此处为 Delphi XE)。
    • 我打赌你会在初始过程中找到对 CoInitializeEx 的调用。
    • @DavidHeffernan:我对源代码做了一个Grep,如果你发现了其他东西,请随时添加。无论如何OleInitialize 在内部调用CoInitializeEx
    • 我在自己的答案中添加了更多细节。我只是想这样做以获得额外的信息。我从你的回答中没有拿走任何东西。您突出显示的初始化是最重要的。 +1
    【解决方案2】:

    如果有疑问,那就去做吧。无论哪种情况,CoInitialize() 都会返回一个您应该检查的hr : HRESULT,因为您需要在SUCCEEDED(hr) 上使用CoUninitialize(),但在FAILED(hr) 时不需要。失败的结果通常表明它已经被调用了。

    引用自您的 MSDN 参考:

    尽管如此,在使用之前始终初始化 COM 是一种很好的做法 这个函数。

    【讨论】:

    • 该问题特意要求消除疑虑。
    • ...这可以通过检查 HRESULT 轻松完成。
    • 这是错误的做法。反复试验永远比容易发现和证明的事实更好。
    • @JensG,MSDN 写道:“要在线程上优雅地关闭 COM 库,每次成功调用 CoInitializeCoInitializeEx,包括任何返回 S_FALSE 的调用,都必须由对 CoUninitialize" 的相应调用,因此对于 CoInitialize[Ex]S_OKS_FALSE 结果都必须调用 CoUninitialize
    • @ALZ:没错,这就是为什么我们有像SUCCEEDED()FAILED()这样的宏/函数,你应该使用它们。而S_FALSE 是成功代码,因此SUCCEEDED(S_FALSE) 的计算结果为true。
    【解决方案3】:

    在 RTL/VCL 源码中,COM 的初始化方式如下:

    1. 通过从Forms.TApplication.Create 拨打OleInitialize。因此,将对所有 VCL 表单应用程序进行此调用,但不会针对服务应用程序进行调用。
    2. 通过在ComObj.InitComObj 中调用CoInitializeCoInitializeEx。这在ComObj 单元的initialization 部分中注册为InitProc。反过来,在您的项目 .dpr 文件代码中对 Application.Initialize 的调用将调用 ComObj.InitComObj
    3. 在 RTL/VCL 周围的许多其他位置。包括但不限于 Datasnap、ComServ、Soap、System.Win.Sensors、Winapi.DirectShow9。其中一些代码领域比 Delphi 7 更新。

    现在,在这些不同的 COM 初始化中,计数的是 1 和 2。在任何标准 VCL 表单应用程序中,这两者都将在启动时在主线程中运行。第 1 项首先运行,因此首先初始化 COM。这才是最重要的初始化。项目 2 运行后返回 S_FALSE 表示 COM 已经初始化。

    所以,对于你的问题:

    我需要在 main/VCL 线程中调用 Coinitialize 吗?

    不,你没有。您可以确定 COM 已经在 VCL 应用程序的主线程中初始化。

    【讨论】:

      猜你喜欢
      • 2017-08-11
      • 2020-01-09
      • 2011-01-18
      • 1970-01-01
      • 2013-09-26
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多