我在控制台应用程序中调用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)
在尝试创建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可能会导致不可预测的行为和令人讨厌的运行时故障.