简体   繁体   English

自动更新Visual Studio扩展

[英]Automatically update Visual Studio Extension

I'm trying to make my extension automatically update itself when new versions are pushed to the Visual Studio Gallery. 当新版本被推送到Visual Studio库时,我正在尝试使我的扩展自动更新。 There are a few guides on how one may achieve this, but they are a couple years old and may not apply. 有一些关于如何实现这一目标的指南,但它们已有几年的历史,可能不适用。

For starters, I'm trying to query the IVsExtensionRepository as follows: 对于初学者,我正在尝试查询IVsExtensionRepository ,如下所示:

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

At Query_ExecuteCompleted I'm receiving an exception from the server: "The remote server returned an error: (400) Bad Request." Query_ExecuteCompleted我收到服务器的异常:“远程服务器返回错误:(400)错误请求。”

A stack trace is provided: 提供堆栈跟踪:

Server stack trace: at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result) at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result) at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeEndService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 服务器堆栈跟踪:位于System.ServiceModel.Channels.ServiceMhannel.SendAsyncResult.End(SendAsyncResult结果)的System.Runtime.AsyncResult.End [TAsyncResult](IAsyncResult结果),位于System.ServiceModel.Channels.ServiceChannel.EndCall(String action,Object)在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage消息)的System.ServiceModel.Channels.ServiceChannelProxy.InvokeEndService(IMethodCallMessage methodCall,ProxyOperationRuntime操作)中的[]出,IAsyncResult结果)

The service is hosted at: https://visualstudiogallery.msdn.microsoft.com/services/dev12/extension.svc 该服务托管在: https//visualstudiogallery.msdn.microsoft.com/services/dev12/extension.svc

Does anyone know how I can create a Visual Studio extension that automatically updates itself from the Visual Studio Gallery? 有谁知道我如何创建一个Visual Studio扩展,从Visual Studio库自动更新自己? Either through the IVsExtensionRepository or manually? 通过IVsExtensionRepository还是手动?

Edit: Now in Visual Studio 2015 extensions are downloaded automatically. 编辑:现在在Visual Studio 2015中自动下载扩展。

So I've completely abandoned querying the IVsExtensionRepository . 所以我完全放弃了查询IVsExtensionRepository I'm not sure why, but there must be some internal problem with the queries it constructs. 我不确定为什么,但它构造的查询必然存在一些内部问题。 I queried the same service using ErikEJ's suggested project, and it worked fine. 我使用ErikEJ建议的项目查询相同的服务,它工作正常。

However, I didn't want to construct the service from the WSDL as it appears SQLCeToolbox has done. 但是,我不想从WSDL构建服务,因为SQLCeToolbox已经完成了。 Instead I used the IVsExtensionRepository , but avoided the CreateQuery() method. 相反,我使用了IVsExtensionRepository ,但避免使用CreateQuery()方法。

Attached is my approach to updating my VSPackage. 附件是我更新我的VSPackage的方法。 You'll need to replace any GUIDs or Package specific names with your package's information. 您需要将任何GUID或Package特定名称替换为您的包的信息。

NOTE There is one Gotcha' in the following code: 注意以下代码中有一个Gotcha':

Note that CodeConnectRepositoryEntry only implements DownloadUrl . 请注意, CodeConnectRepositoryEntry仅实现DownloadUrl When updating the VSPackage, this is all one must worry about as it allows us to download the new package. 更新VSPackage时,这是必须担心的,因为它允许我们下载新包。 This URL can be found on the VSGallery page for your VSPackage. 可以在VSPackage的VSGallery页面上找到此URL。

However : You must trim the URL as follows: 但是 :您必须按如下方式修剪URL:

http://visualstudiogallery.msdn.microsoft.com/c0c2ad47-957c-4e07-89fc-20996595b6dd/file/140793/4/CodeConnectAlpha.vsix 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/ http://visualstudiogallery.msdn.microsoft.com/c0c2ad47-957c-4e07-89fc-20996595b6dd/file/140793/

Above, the /4/ represents the fourth upload. 上面,/ 4 /代表第四次上传。 By removing it completely, the Visual Studio Gallery will download the latest version. 通过完全删除它,Visual Studio Gallery将下载最新版本。

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

I have some code to access the service and produce a RSS feed from it here: sqlcetoolbox.codeplex.com/SourceControl/latest - In the NuGetDownloadfedd.zip file (has nothing to do with Nuget!) - Also includes the version number: 我有一些代码来访问该服务并在此处生成RSS源:sqlcetoolbox.codeplex.com/SourceControl/latest - 在NuGetDownloadfedd.zip文件中(与Nuget无关!) - 还包括版本号:

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

In fact I am already hosting a RSS feed service, let me know if you would like to use it. 事实上,我已经托管了RSS提要服务,如果您想使用它,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM