5

Visual Studio是否有一個協議處理程序,其中包含打開特定文件的命令?Visual Studio協議處理程序 - 打開文件

他們有一個GIT中克隆,如Announcing the GitHub Extension for Visual Studio描述:

開放在Visual Studio按鈕[在GitHub上]調用名爲「混帳客戶端://」新協議處理程序。我們一起設計了這個新的通用協議與GitHub的允許網站通過標準的Git操作任何IDE

從本質上講就是我想要做這個GitHub Issues描述:

enter image description here

當我點擊在按鈕上,Visual Studio應打開特定文件(最好使用正確的Solution加載)。

如果這不可能直接與協議處理程序一起使用,是否可以將其作爲具有Web視圖的Visual Studio Extensions完成,以實現相同的目的(即允許從網頁打開文件)?

回答

2

通過創建一個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; 
    } 
} 

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