代码之家  ›  专栏  ›  技术社区  ›  Philip Pittle

Visual Studio协议处理程序-打开文件

  •  8
  • Philip Pittle  · 技术社区  · 10 年前

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

    他们有一个Git克隆,如中所述 Announcing the GitHub Extension for Visual Studio :

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

    本质上,我想做的事情描述如下 GitHub Issues :

    enter image description here

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

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

    1 回复  |  直到 10 年前
        1
  •  4
  •   Philip Pittle    10 年前

    我通过创建一个Visual Studio插件,该插件带有一个自托管的Owin服务器,它公开了一个基本的WebApi,从而能够接近我想要的内容。

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

    Opening files in Visual Studio via a web browser

    任何托管此按钮的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;
        }
    }
    

    网络应用程序

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