无法从 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;

也许这会帮助其他人解决类似的问题。