8

Visual Studio 是否具有包含打开特定文件的命令的协议处理程序?

他们有一个用于 Git 克隆,如宣布 Visual Studio 的 GitHub 扩展中所述:

[在 GitHub 中] 在 Visual Studio 中打开按钮调用一个名为“git-client://”的新协议处理程序。我们与 GitHub 一起设计了这个新的通用协议,以允许网站将标准 Git 操作传递给任何 IDE

基本上我想要做的是在这个GitHub 问题中描述:

在此处输入图像描述

当我单击按钮时,Visual Studio 应该打开特定文件(最好也加载正确的解决方案)。

如果这不能直接使用协议处理程序,是否可以作为具有 Web 视图的 Visual Studio 扩展来实现相同目的(即允许从网页打开文件)?

4

1 回答 1

4

通过创建一个带有自托管 Owin 服务器并公开基本 WebApi 的 Visual Studio 插件,我能够足够接近我想要的东西。

这允许我从浏览器打开文件,链接如下: http://localhost:9000/VisualStudioApi/OpenFile?Path=.\Url\Escaped\Path\Relative\To\Solution\File

通过 Web 浏览器在 Visual Studio 中打开文件

托管此按钮的任何 Web 服务器都需要对指向 的链接进行硬编码http://localhost:9000,这会带来运行多个 Visual Studio 实例的问题,因此需要一些关于如何将 .sln 文件映射到已知端口的逻辑。但是没有官方的 Visual Studio 解决方案,这在很大程度上完成了工作。


如果这对将来的某人有帮助,这里是代码片段:

VS 包

[ComVisible(true)]
[Guid("B77F7C65-0F9F-422A-A897-C06FDAEC9604")]
[ProvideObject(typeof(InitializerPackage))]
[ProvideAutoLoad(UIContextGuids80.SolutionExists)]
public class InitializerPackage : Package
{
    protected override void Initialize()
    {
        base.Initialize();

        //Get copy of current DTE
        var dte = (DTE)GetService(typeof(DTE));
        var dte2 = dte as DTE2;

        dte2.Events.SolutionEvents.Opened += () => 
             OwinVisualStudioApiListenerManager.StartServer(dte2);
        dte2.Events.SolutionEvents.AfterClosing += () => 
             OwinVisualStudioApiListenerManager.StopServer();           
    }
}

Owin 初始化器

public static class OwinVisualStudioApiListenerManager
{
    private static IDisposable _runningServer;

    public static DTE2 VisualStudioApi { get; set; }

    public static void StartServer(DTE2 visualStudioApi)
    {
        if (null != _runningServer)
            _runningServer.Dispose();

        VisualStudioApi = visualStudioApi;

        //nothing fancy about OwinStartup
        //see github file http://tinyurl.com/zt2bm8b
        _runningServer = WebApp.Start<OwinStartup>("http://localhost:9000");
    }

    public static void StopServer()
    {
        if (null != _runningServer)
            _runningServer.Dispose();

        VisualStudioApi = null;
    }
}

WebAPI

public class VisualStudioApiController : ApiController
{
    // GET /VisualStudioApi/OpenFile/?path=
    [HttpGet]
    public string OpenFile(string path)
    {
         var fullPath = Path.Combine(
                Path.GetDirectoryName(
                    OwinVisualStudioApiListenerManager.VisualStudioApi.Solution.FullName),
                HttpUtility.UrlDecode(path));

          //http://stackoverflow.com/q/5039226/1224069
          OwinVisualStudioApiListenerManager.VisualStudioApi
                .ExecuteCommand(
                    "File.OpenFile",
                    fullPath);

           return "success";
    }
}
于 2016-01-05T19:51:23.460 回答