模块中的异常EOleSysError

use*_*395 1 delphi delphi-7

我在控制台应用程序中调用AddExceptionToFirewall时收到错误

尚未调用CoInitialize模块中的异常EOleSysError

如何修复它为什么我甚至在使用子句中使用ComObj,ActiveX时会出现此错误?

Procedure AddExceptionToFirewall(Const Caption, Executable: String);
      const
       NET_FW_PROFILE2_DOMAIN  = 1;
       NET_FW_PROFILE2_PRIVATE = 2;
       NET_FW_PROFILE2_PUBLIC  = 4;
       NET_FW_IP_PROTOCOL_TCP = 6;
       NET_FW_ACTION_ALLOW    = 1;
      var
      fwPolicy2      : OleVariant;
      RulesObject    : OleVariant;
      Profile        : Integer;
      NewRule        : OleVariant;
      begin
      Profile             := NET_FW_PROFILE2_PRIVATE OR NET_FW_PROFILE2_PUBLIC;
      fwPolicy2           := CreateOleObject('HNetCfg.FwPolicy2');
      RulesObject         := fwPolicy2.Rules;
      NewRule             := CreateOleObject('HNetCfg.FWRule');
      NewRule.Name        := Caption;
      NewRule.Description := Caption;
      NewRule.Applicationname := Executable;
      NewRule.Protocol := NET_FW_IP_PROTOCOL_TCP;
      NewRule.Enabled := TRUE;
      NewRule.Profiles := Profile;
      NewRule.Action := NET_FW_ACTION_ALLOW;
      RulesObject.Add(NewRule);
     end;
Run Code Online (Sandbox Code Playgroud)

Mar*_*der 5

在尝试创建COM对象之前,需要在应用程序中调用OleInitialize(或OleInitializeEx).

MSDN:OleInitialize函数 初始化当前单元中的COM库,将并发模型标识为单线程单元(STA),并启用下面"备注"部分中描述的其他功能.应用程序必须初始化COM库,然后才能调用除CoGetMalloc和内存分配函数之外的COM库函数.

我在我的主单位做到这一点:

initialization
  OleInitialize(nil);

finalization
  OleUninitialize;
Run Code Online (Sandbox Code Playgroud)

此功能在ActiveX单元中(通过外部),但不会由该单元自动调用.可能是其他单位会打电话给这个.这取决于你的功能何时运行.

这是一个Stackoverflow问题,询问有关两次调用OleInitialize.

另请注意,这是特定于线程的.如果正在启动运行此函数的另一个线程,则需要在该线程上调用OleInitialize.

这是另一个很好的页面,详细介绍了:COM客户端内部

该页面的相关报价:

在标准的Delphi EXE COM应用程序中,CoOitialize/Ex和CoUninitialize从ComObj模块中自动调用.CoInitialize/Ex进程通过从TApplication.Initialize调用的InitProc初始化序列进行链接.因此,重要的是调用Application.Initialize(通常在DPR文件中)作为EXE应用程序中的第一个语句.

忘记调用Application.Initialize的效果通常是在尝试进行COM调用的第一个语句,或者更具体地说,是导出/导入COM接口指针的第一个语句时,令人讨厌的"CoInitialize尚未被调用"错误.另外,ComObj仅针对EXE调用CoInitialize/Ex,而不针对DLL调用CoInitialize/Ex.DLL的生命周期和线程要求是其主机应用程序的子集.因此,主机应用程序负责在调用DLL应用程序之前初始化COM运行时.在DLL中显式调用CoInitialize/Ex可能会导致不可预测的行为和令人讨厌的运行时故障.