Не удается получить ссылки на пакеты, зарегистрированные для экземпляра Visual Studio 17 и выше из Pascal Script - PullRequest
0 голосов
/ 05 марта 2019

Мне нужно определить, установлено ли конкретное расширение в Visual Studio 2017. Я могу получить ссылки на пакеты, зарегистрированные на экземпляр VS, используя Microsoft.VisualStudio.Setup.Configuration.Interop с C #.Вот пример рабочего кода:

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);

Проблема в том, что я должен сделать это, используя Inno Setup с его скриптом Pascal.На данный момент у меня есть следующий код:

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 пусто.

Кто-нибудь знает, как я могу получить действительный массив расширений и заставить этот метод работать?

Заранее спасибо.

1 Ответ

0 голосов
/ 05 марта 2019

Мне удалось решить проблему благодаря комментарию Мартина Прикрыла (еще раз спасибо).

Метод GetPackages() объявлен в интерфейсе ISetupInstance2, унаследованот ISetupInstance.Следовательно, методы из ISetupInstance должны были быть объявлены при объявлении ISetupInstance2.

Объявление интерфейса ISetupInstance2 для использования метода GetPackages() должно выглядеть следующим образом:

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;

Может быть, это поможет кому-то решить подобные проблемы.

...