无法从 Pascal 脚本中获取注册到 Visual Studio 17 及更高版本实例的包引用
Can't get package references registered to an instance of Visual Studio 17 and above from Pascal Script
我需要定义是否在 Visual Studio 2017 中安装了特定扩展。我可以使用 Microsoft.VisualStudio.Setup.Configuration.Interop
和 C# 获取注册到 VS 实例的包引用。这是工作代码的示例:
var query = (ISetupConfiguration2) new SetupConfiguration();
var e = query.EnumInstances();
int fetched;
var instances = new ISetupInstance[1];
do
{
e.Next(1, instances, out fetched);
if (fetched <= 0) continue;
ISetupInstance2 instance = instances[0] as ISetupInstance2;
if (instance == null)
continue;
var temp = instance.GetPackages();
var temp2 = temp.Select(p => p.GetId());
} while (fetched > 0);
问题是我必须使用带有 Pascal 脚本的 Inno Setup 来完成它。此时我有以下代码:
const
CLSID_SetupConfiguration = '{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}';
type
ISetupPackageReference = interface(IUnknown)
'{DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5}'
function GetId(out result: WideString): HResult;
end;
packageReference = array[0..10] of ISetupPackageReference;
ISetupInstance2 = interface(IUnknown)
'{89143C9A-05AF-49B0-B717-72E218A2185C}'
function GetPackages(out pack: packageReference): HResult;
end;
arrISetupInstance2 = array[1..1] of ISetupInstance2;
IEnumSetupInstances = interface(IUnknown)
'{6380BCFF-41D3-4B2E-8B2E-BF8A6810C848}'
function Next(celt: Integer; var rgelt: arrISetupInstance2; out pceltFetched: Integer): HResult;
function Skip(celt: Integer): HResult;
function Reset: HResult;
function Clone(out pEnumSetupInstances: IEnumSetupInstances): HResult;
end;
ISetupConfiguration = interface(IUnknown)
'{42843719-DB4C-46C2-8E7C-64F1816EFD5B}'
function EnumInstances(out pEnumSetupInstances: IEnumSetupInstances): HResult;
end;
ISetupConfiguration2 = interface(IUnknown)
'{26AAB78C-4A60-49D6-AF3B-3C35BC93365D}'
function EnumInstances(out pEnumSetupInstances: IEnumSetupInstances): HResult;
end;
procedure GetArrayOfVSExtensions;
var
MyResult: String;
obj: IUnknown;
setupConfiguration: ISetupConfiguration2;
setupInstances: IEnumSetupInstances;
instances: arrISetupInstance2;
instance: ISetupInstance2;
fetched: Integer;
hr: HResult;
MyPackages: packageReference;
FirstInstance: ISetupPackageReference;
NameOfExtension: WideString;
begin
obj := CreateComObject(StringToGUID(CLSID_SetupConfiguration));
setupConfiguration := ISetupConfiguration2(obj);
hr := setupConfiguration.EnumInstances(setupInstances);
fetched := 0;
hr := setupInstances.Next(1, instances, fetched);
instance := instances[1];
hr := instance.GetPackages(MyPackages);
FirstInstance := MyPackages[3];
hr := FirstInstance.GetId(NameOfExtension); { Here I get null pointer exception }
end;
在我的情况下,方法 GetPackages()
似乎无法正常工作,结果 MyPackages
为空。
有谁知道如何获得有效的扩展数组并使此方法有效?
提前致谢。
感谢 Martin Prikryl 的评论,我设法解决了问题(再次感谢您)。
GetPackages()
方法声明在ISetupInstance2
接口中,继承自ISetupInstance
。因此,在声明 ISetupInstance2
.
时必须声明来自 ISetupInstance
的方法
为了使用 GetPackages()
方法,ISetupInstance2
接口的声明必须如下所示:
ISetupInstance2 = interface(IUnknown)
'{89143C9A-05AF-49B0-B717-72E218A2185C}'
{ Inherited methods from ISetupInstance }
function GetInstanceId(out id: WideString): HResult;
procedure Dummy2;
function GetInstallationName(out installationName: WideString): HResult;
function GetInstallationPath(out installationName: WideString): HResult;
function GetInstallationVersion(out installationVersion: WideString): HResult;
function GetDisplayName(lcid: Integer; out displayName: WideString): HResult;
function GetDescription(lcid: Integer; out description: WideString): HResult;
function ResolvePath(pwszRelativePath: WideString; out result: WideString): HResult;
{ Own methods of ISetupInstance2 }
procedure Dummy3;
function GetPackages(out pack: packageReference): HResult;
procedure Dummy4;
procedure Dummy5;
procedure Dummy6;
procedure Dummy7;
procedure Dummy8;
procedure Dummy9;
procedure Dummy10;
end;
也许这会帮助其他人解决类似的问题。
我需要定义是否在 Visual Studio 2017 中安装了特定扩展。我可以使用 Microsoft.VisualStudio.Setup.Configuration.Interop
和 C# 获取注册到 VS 实例的包引用。这是工作代码的示例:
var query = (ISetupConfiguration2) new SetupConfiguration();
var e = query.EnumInstances();
int fetched;
var instances = new ISetupInstance[1];
do
{
e.Next(1, instances, out fetched);
if (fetched <= 0) continue;
ISetupInstance2 instance = instances[0] as ISetupInstance2;
if (instance == null)
continue;
var temp = instance.GetPackages();
var temp2 = temp.Select(p => p.GetId());
} while (fetched > 0);
问题是我必须使用带有 Pascal 脚本的 Inno Setup 来完成它。此时我有以下代码:
const
CLSID_SetupConfiguration = '{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}';
type
ISetupPackageReference = interface(IUnknown)
'{DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5}'
function GetId(out result: WideString): HResult;
end;
packageReference = array[0..10] of ISetupPackageReference;
ISetupInstance2 = interface(IUnknown)
'{89143C9A-05AF-49B0-B717-72E218A2185C}'
function GetPackages(out pack: packageReference): HResult;
end;
arrISetupInstance2 = array[1..1] of ISetupInstance2;
IEnumSetupInstances = interface(IUnknown)
'{6380BCFF-41D3-4B2E-8B2E-BF8A6810C848}'
function Next(celt: Integer; var rgelt: arrISetupInstance2; out pceltFetched: Integer): HResult;
function Skip(celt: Integer): HResult;
function Reset: HResult;
function Clone(out pEnumSetupInstances: IEnumSetupInstances): HResult;
end;
ISetupConfiguration = interface(IUnknown)
'{42843719-DB4C-46C2-8E7C-64F1816EFD5B}'
function EnumInstances(out pEnumSetupInstances: IEnumSetupInstances): HResult;
end;
ISetupConfiguration2 = interface(IUnknown)
'{26AAB78C-4A60-49D6-AF3B-3C35BC93365D}'
function EnumInstances(out pEnumSetupInstances: IEnumSetupInstances): HResult;
end;
procedure GetArrayOfVSExtensions;
var
MyResult: String;
obj: IUnknown;
setupConfiguration: ISetupConfiguration2;
setupInstances: IEnumSetupInstances;
instances: arrISetupInstance2;
instance: ISetupInstance2;
fetched: Integer;
hr: HResult;
MyPackages: packageReference;
FirstInstance: ISetupPackageReference;
NameOfExtension: WideString;
begin
obj := CreateComObject(StringToGUID(CLSID_SetupConfiguration));
setupConfiguration := ISetupConfiguration2(obj);
hr := setupConfiguration.EnumInstances(setupInstances);
fetched := 0;
hr := setupInstances.Next(1, instances, fetched);
instance := instances[1];
hr := instance.GetPackages(MyPackages);
FirstInstance := MyPackages[3];
hr := FirstInstance.GetId(NameOfExtension); { Here I get null pointer exception }
end;
在我的情况下,方法 GetPackages()
似乎无法正常工作,结果 MyPackages
为空。
有谁知道如何获得有效的扩展数组并使此方法有效?
提前致谢。
感谢 Martin Prikryl 的评论,我设法解决了问题(再次感谢您)。
GetPackages()
方法声明在ISetupInstance2
接口中,继承自ISetupInstance
。因此,在声明 ISetupInstance2
.
ISetupInstance
的方法
为了使用 GetPackages()
方法,ISetupInstance2
接口的声明必须如下所示:
ISetupInstance2 = interface(IUnknown)
'{89143C9A-05AF-49B0-B717-72E218A2185C}'
{ Inherited methods from ISetupInstance }
function GetInstanceId(out id: WideString): HResult;
procedure Dummy2;
function GetInstallationName(out installationName: WideString): HResult;
function GetInstallationPath(out installationName: WideString): HResult;
function GetInstallationVersion(out installationVersion: WideString): HResult;
function GetDisplayName(lcid: Integer; out displayName: WideString): HResult;
function GetDescription(lcid: Integer; out description: WideString): HResult;
function ResolvePath(pwszRelativePath: WideString; out result: WideString): HResult;
{ Own methods of ISetupInstance2 }
procedure Dummy3;
function GetPackages(out pack: packageReference): HResult;
procedure Dummy4;
procedure Dummy5;
procedure Dummy6;
procedure Dummy7;
procedure Dummy8;
procedure Dummy9;
procedure Dummy10;
end;
也许这会帮助其他人解决类似的问题。