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

Когда я нажимаю на Button, Visual Studio должен открыть конкретный файл (желательно с правильным загруженным решением).

Если это невозможно напрямую с обработчиками протоколов, возможно ли это сделать как расширение Visual Studio с веб-представлением, которое достигнет той же цели (т.е. разрешить открытие файлов с веб-страницы)?

ответ

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

Любой веб-сервер, эту кнопку нужно будет жёстко ссылки на 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 Initializer

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"; 
    } 
} 
Смежные вопросы