Автоматически обновлять расширение Visual Studio

Я пытаюсь сделать так, чтобы мое расширение автоматически обновлялось при добавлении новых версий в галерею Visual Studio. Есть несколько руководств о том, как этого добиться, но они рассчитаны на пару лет и могут не применяться.

Для начала я пытаюсь запросить _1 _ следующим образом:

var _extensionRepository = (IVsExtensionRepository)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsExtensionRepository));

var query = _extensionRepository.CreateQuery<VSGalleryEntry>(false, true)
                .OrderByDescending(n => n.Ranking)
                .Skip(0)
                .Take(25) as IVsExtensionRepositoryQuery<VSGalleryEntry>;

query.ExecuteCompleted += Query_ExecuteCompleted;
query.ExecuteAsync();

В Query_ExecuteCompleted я получаю исключение от сервера: «Удаленный сервер возвратил ошибку: (400) неверный запрос».

Предоставляется трассировка стека:

Трассировка стека сервера: в System.Runtime.AsyncResult.End [TAsyncResult] (результат IAsyncResult) в System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End (результат SendAsyncResult) в System.ServiceModel.Channel.ServiceModel.Channel.ServiceModel.Channel.Service Action [] out, результат IAsyncResult) в System.ServiceModel.Channels.ServiceChannelProxy.InvokeEndService (IMethodCallMessage methodCall, операция ProxyOperationRuntime) в System.ServiceModel.Channels.ServiceChannelProxy.Invoke (сообщение IMethodCallMessage)

Служба размещена по адресу: https://visualstudiogallery.msdn.microsoft.com/services/dev12/extension.svc

Кто-нибудь знает, как я могу создать расширение Visual Studio, которое автоматически обновляется из галереи Visual Studio? Либо через IVsExtensionRepository, либо вручную?


person JoshVarty    schedule 23.09.2014    source источник
comment
Хм, возможно, вам придется настроить трассировку пакетов и посмотреть, какой из отправляемых запросов является недопустимым.   -  person JaredPar    schedule 24.09.2014
comment
Да, думаю, я попробую. Это все через SSL, но я думаю, что это все еще возможно, мне просто нужно время, чтобы узнать, как это сделать.   -  person JoshVarty    schedule 24.09.2014


Ответы (2)


Изменить: теперь в Visual Studio 2015 расширения загружаются автоматически.

Поэтому я полностью отказался от запросов IVsExtensionRepository. Я не уверен, почему, но должна быть какая-то внутренняя проблема с запросами, которые он создает. Я запросил тот же сервис, используя предложенный ErikEJ проект, и он работал нормально.

Однако я не хотел создавать службу из WSDL, поскольку, похоже, это сделал SQLCeToolbox. Вместо этого я использовал IVsExtensionRepository, но избегал метода CreateQuery().

Прилагаю мой подход к обновлению моего пакета VSPackage. Вам нужно будет заменить любые идентификаторы GUID или конкретные имена пакетов информацией о вашем пакете.

ПРИМЕЧАНИЕ. В следующем коде есть одна ошибка:

Обратите внимание, что CodeConnectRepositoryEntry реализует только DownloadUrl. При обновлении VSPackage это все, о чем нужно беспокоиться, поскольку это позволяет нам загрузить новый пакет. Этот URL-адрес можно найти на странице VSGallery для вашего VSPackage.

Однако: необходимо обрезать URL-адрес следующим образом:

http://visualstudiogallery.msdn.microsoft.com/c0c2ad47-957c-4e07-89fc-20996595b6dd/file/140793/4/CodeConnectAlpha.vsix

to:

http://visualstudiogallery.msdn.microsoft.com/c0c2ad47-957c-4e07-89fc-20996595b6dd/file/140793/

Выше / 4 / представляет четвертую загрузку. После его полного удаления из галереи Visual Studio будет загружена последняя версия.

internal class CodeConnectUpdater
{
    IVsExtensionManager _extensionManager;

    IVsExtensionRepository _extensionRepository;

    //We need only supply the download URL.
    //This can be retrieved from the "Download" button on your extension's page.
    private class CodeConnectRepositoryEntry : IRepositoryEntry
    {
        public string DownloadUpdateUrl
        {
            get; set;
        }

        public string DownloadUrl
        {
            get
            {
                //NOTE: YOU MUST TRIM THE DOWNLOAD URL
                //TO NOT CONTAIN A VERSION. THIS FORCES 
                //THE GALLERY TO DOWNLOAD THE LATEST VERSION
                return "http://visualstudiogallery.msdn.microsoft.com/c0c2ad47-957c-4e07-89fc-20996595b6dd/file/140793/";
            }
            set
            {
                throw new NotImplementedException("Don't overwrite this.");
            }
        }

        public string VsixReferences
        {
            get; set;
        }
    }

    //I have been calling this from the VSPackage's Initilize, passing in the component model
    public bool CheckForUpdates(IComponentModel componentModel)
    {
        _extensionRepository = (IVsExtensionRepository)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsExtensionRepository));
        _extensionManager = (IVsExtensionManager)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsExtensionManager));
        //Find the extension you're after.
        var extension = _extensionManager.GetInstalledExtensions().Where(n => n.Header.Name == "Code Connect Alpha").SingleOrDefault();

        return CheckAndInstallNewVersion(extension);
    }

    private bool CheckAndInstallNewVersion(IInstalledExtension myExtension)
    {
        var needsRestart = false;
        var entry = new CodeConnectRepositoryEntry();
        var newVersion = FetchIfUpdated(myExtension, entry);
        if (newVersion != null)
        {
            Install(myExtension, newVersion);
            needsRestart = true;
        }

        return needsRestart;
    }

    //Checks the version of the extension on the VS Gallery and downloads it if necessary.
    private IInstallableExtension FetchIfUpdated(IInstalledExtension extension, CodeConnectRepositoryEntry entry)
    {
        var version = extension.Header.Version;
        var strNewVersion = _extensionRepository.GetCurrentExtensionVersions("ExtensionManagerQuery", new List<string>() { "6767f237-b6e4-4d95-9982-c9e898f72502" }, 1033).Single();
        var newVersion = Version.Parse(strNewVersion);

        if (newVersion > version)
        {
            var newestVersion = _extensionRepository.Download(entry);
            return newestVersion;
        }

        return null;
    }

    private RestartReason Install(IInstalledExtension currentExtension, IInstallableExtension updatedExtension)
    {
        //Uninstall old extension
        _extensionManager.Disable(currentExtension);
        _extensionManager.Uninstall(currentExtension);

        //Install new version
        var restartReason = _extensionManager.Install(updatedExtension, false);

        //Enable the newly installed version of the extension
        var newlyInstalledVersion = _extensionManager.GetInstalledExtension(updatedExtension.Header.Identifier);
        if (newlyInstalledVersion != null)
        {
            _extensionManager.Enable(newlyInstalledVersion);
        }

        return restartReason;
    }
}
person JoshVarty    schedule 29.09.2014

У меня есть код для доступа к сервису и создания из него RSS-канала: sqlcetoolbox.codeplex.com/SourceControl/latest - В файле NuGetDownloadfedd.zip (не имеет ничего общего с Nuget!) - Также включает номер версии:

 foundItem.Project.Metadata.TryGetValue("VsixVersion", out version);

На самом деле я уже размещаю службу RSS-каналов, дайте мне знать, если вы хотите ее использовать.

person ErikEJ    schedule 24.09.2014
comment
Знаете ли вы значение LCID, равного 1033 в FeedHandler.cs? (Если нет, то я просто понятия не имею, что это означает) - person JoshVarty; 29.09.2014
comment
Вы делаете вид, что вызываете веб-сервис из английской версии Visual Studio ... - person ErikEJ; 29.09.2014