我正在尝试将以下javascript代码移植到inno-setup pascal脚本:
var adminManager = new ActiveXObject('Microsoft.ApplicationHost.AdminManager');
var appPoolsSection = adminManager.GetAdminSection('system.applicationHost/applicationPools', 'MACHINE/WEBROOT/APPHOST');
var appPoolsCollection = applicationPoolsSection.Collection;
for (var i = 0; i < appPoolsCollection.Count; i++)
{
var appPool = appPoolsCollection.Item(i);
// doing someting with the application pool
}
此代码已翻译为:
var AdminManager, AppPoolsSection, AppPoolsCollection, AppPool: Variant;
i: Integer;
begin
AdminManager := CreateOleObject('Microsoft.ApplicationHost.AdminManager');
AppPoolsSection := AdminManager.GetAdminSection('system.applicationHost/applicationPools', 'MACHINE/WEBROOT/APPHOST');
AppPoolsCollection := AppPoolsSection.Collection;
for i := 0 to AppPoolsCollection.Count-1 do begin
AppPool := AppPoolsCollection.Item(i);
// doing someting with the application pool
end;
end;
但它在AppPoolsCollection := AppPoolsSection.Collection
行引发了以下错误:
Exception: Could not convert variant of type (Unknown) into type (Dispatch).
我可以做任何事情来告知pascal scritp AppPoolsSection
对象是IDispach
而不仅仅是IUnknown
?
答案 0 :(得分:2)
我找到了一个有效且比“导入”接口定义更简单的解决方案。
此代码中使用的所有COM组件都实现了IDispatch(它需要在VBScript或JScript上使用),然后我导入VariantChangeType函数将IUnknown引用强制转换为IDispatch引用(因为它看起来不是在pascal脚本上得到支持。)
关注最终代码:
function VariantChangeType(out Dest: Variant; Source: Variant; Flags, vt: Word): HRESULT; external 'VariantChangeType@oleaut32.dll stdcall';
function VarToDisp(Source: Variant): Variant;
begin
Result := Unassigned;
OleCheck(VariantChangeType(Result, Source, 0, varDispatch));
end;
procedure EnumerateAppPools(AppPools: TStrings);
var AdminManager, Section, Collection, Item, Properties: Variant;
i: Integer;
begin
AdminManager := CreateOleObject('Microsoft.ApplicationHost.AdminManager');
Section := VarToDisp(AdminManager.GetAdminSection('system.applicationHost/applicationPools', 'MACHINE/WEBROOT/APPHOST'));
Collection := VarToDisp(Section.Collection);
for i := 0 to Collection.Count-1 do begin
Item := VarToDisp(Collection.Item(i));
Properties := VarToDisp(Item.Properties);
if (VarToDisp(Properties.Item('managedPipelineMode')).Value = 1) and
(VarToDisp(Properties.Item('managedRuntimeVersion')).Value = 'v4.0') then
AppPools.Add(VarToDisp(Properties.Item('name')).Value);
end;
end;