Откройте файл в Visual Studio с определенным номером строки



у меня есть утилита (grep), которая дает мне список имен файлов и номера строк. После того, как я определил, что devenv является правильной программой для открытия файла, я хотел бы убедиться, что он открыт по указанному номеру строки. В emacs это будет:



emacs +140 filename.c


Я не нашел ничего подобного для Visual Studio (devenv). Самое близкое, что я нашел, это:



devenv /Command "Edit.Goto 140" filename.c


однако, это делает отдельный экземпляр devenv для каждого такого файла. Я бы предпочел что-то, что использует существующий экземпляр.



эти варианты повторно использовать существующий devenv, но не переходите к указанной строке:



devenv /Command "Edit.Goto 140" /Edit filename.c
devenv /Command /Edit filename.c "Edit.Goto 140"


Я думал, что использование нескольких аргументов "/Command" может сделать это, но у меня, вероятно, нет правильного, потому что я либо получаю ошибки, либо вообще не отвечаю (кроме открытия пустого devenv).



Я мог бы написать специальный макрос для devenv, но я хотел бы, чтобы эта утилита использовалась другими, у которых нет этого макроса. И я не понимаю, как вызвать этот макрос с опцией "/Command".



какие идеи?





Ну, не похоже, что есть способ сделать это, как я хотел. Поскольку похоже, что мне понадобится выделенный код для запуска Visual Studio, я решил использовать EnvDTE, как показано ниже. Надеюсь, это поможет кому-то еще.



#include "stdafx.h"

//-----------------------------------------------------------------------
// This code is blatently stolen from http://benbuck.com/archives/13
//
// This is from the blog of somebody called "BenBuck" for which there
// seems to be no information.
//-----------------------------------------------------------------------

// import EnvDTE
#pragma warning(disable : 4278)
#pragma warning(disable : 4146)
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("8.0") lcid("0") raw_interfaces_only named_guids
#pragma warning(default : 4146)
#pragma warning(default : 4278)

bool visual_studio_open_file(char const *filename, unsigned int line)
{
HRESULT result;
CLSID clsid;
result = ::CLSIDFromProgID(L"VisualStudio.DTE", &clsid);
if (FAILED(result))
return false;

CComPtr<IUnknown> punk;
result = ::GetActiveObject(clsid, NULL, &punk);
if (FAILED(result))
return false;

CComPtr<EnvDTE::_DTE> DTE;
DTE = punk;

CComPtr<EnvDTE::ItemOperations> item_ops;
result = DTE->get_ItemOperations(&item_ops);
if (FAILED(result))
return false;

CComBSTR bstrFileName(filename);
CComBSTR bstrKind(EnvDTE::vsViewKindTextView);
CComPtr<EnvDTE::Window> window;
result = item_ops->OpenFile(bstrFileName, bstrKind, &window);
if (FAILED(result))
return false;

CComPtr<EnvDTE::Document> doc;
result = DTE->get_ActiveDocument(&doc);
if (FAILED(result))
return false;

CComPtr<IDispatch> selection_dispatch;
result = doc->get_Selection(&selection_dispatch);
if (FAILED(result))
return false;

CComPtr<EnvDTE::TextSelection> selection;
result = selection_dispatch->QueryInterface(&selection);
if (FAILED(result))
return false;

result = selection->GotoLine(line, TRUE);
if (FAILED(result))
return false;

return true;
}
632   11  

11 ответов:

Я не могу найти способ сделать это с помощью прямых параметров командной строки. Похоже, вам придется написать макрос для этого. Предположительно, вы можете вызвать их так.

devenv /command "Macros.MyMacros.Module1.OpenFavoriteFiles"

таким образом, вы, вероятно, можете создать макрос, который принимает имя файла и номер строки, а затем открывает файл и переходит в нужное место. Но, я не знаю, что вы можете указать флаг того же экземпляра где-то, или нет.

С VS2008 С пакетом обновления 1, вы можете использовать следующую командную строку, чтобы открыть файл в определенной строке в существующем экземпляре:

devenv /edit FILE_PATH /command "edit.goto FILE_LINE"

источник

разрабатывая вопрос и ответ Гарольда, я адаптировал решение C++ (которое я впервые принял) к C#. Это намного проще (это моя первая программа на C#!). Нужно просто создать проект, добавить ссылки на " envDTE "и" envDTE80 " и отбросить следующий код:

using System;
using System.Collections.Generic;
using System.Text;

namespace openStudioFileLine
{
    class Program    
    {
        [STAThread]
        static void Main(string[] args)     
        {
            try          
            {
                String filename = args[0];
                int fileline;
                int.TryParse(args[1], out fileline);
                EnvDTE80.DTE2 dte2;
                dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE");
                dte2.MainWindow.Activate();
                EnvDTE.Window w = dte2.ItemOperations.OpenFile(filename, EnvDTE.Constants.vsViewKindTextView);
                ((EnvDTE.TextSelection)dte2.ActiveDocument.Selection).GotoLine(fileline, true);
            }
            catch (Exception e)          
            {          
                Console.Write(e.Message);      
            }
        }
    }
}

один тогда просто звонит openStudioFileLine path_to_file numberOfLine.

надеюсь, что это может помочь !

на основе Редер ответ я опубликовал репозиторий с исходным,вот двоичный файл (. net2.0)

Я также добавляю поддержку нескольких версий VS

usage: <version> <file path> <line number> 

Visual Studio version                 value 
VisualStudio 2002                     2 
VisualStudio 2003                     3 
VisualStudio 2005                     5 
VisualStudio 2008                     8 
VisualStudio 2010                    10 
VisualStudio 2012                    12 
VisualStudio 2013                    13 

пример использования от GrepWin:

VisualStudioFileOpenTool.exe 12 %path% %line%

довольно старый поток, но это заставило меня начать так вот еще один пример. Это AutoHotkey функция открывает файл и помещает курсор на определенную строку и столбец.

; http://msdn.microsoft.com/en-us/library/envdte.textselection.aspx
; http://msdn.microsoft.com/en-us/library/envdte.textselection.movetodisplaycolumn.aspx
VST_Goto(Filename, Row:=1, Col:=1) {
    DTE := ComObjActive("VisualStudio.DTE.12.0")
    DTE.ExecuteCommand("File.OpenFile", Filename)
    DTE.ActiveDocument.Selection.MoveToDisplayColumn(Row, Col)
}

звонок с:

VST_Goto("C:\Palabra\.NET\Addin\EscDoc\EscDoc.cs", 328, 40)

вы можете перевести его почти по строкам в VBScript или JScript.

вот вариация VBS решения Гарольда:по ссылке .VBS скрипт.

open-in-msvs.vbs full-path-to-file line column

Windows поддерживает VBScript изначально - нет необходимости в компиляции или каких-либо дополнительных интерпретаторах.

вот вариант Python решения Гарольда:

import sys
import win32com.client

filename = sys.argv[1]
line = int(sys.argv[2])
column = int(sys.argv[3])

dte = win32com.client.GetActiveObject("VisualStudio.DTE")

dte.MainWindow.Activate
dte.ItemOperations.OpenFile(filename)
dte.ActiveDocument.Selection.MoveToLineAndOffset(line, column+1)

он показывает, как перейти к указанной строке + столбец.

для справки вот ENVDE, написанный на C# (используя O2 Платформа внутри VisualStudio, чтобы получить ссылку на живой объект DTE)

var visualStudio = new API_VisualStudio_2010();

var vsDTE = visualStudio.VsAddIn.VS_Dte;
//var document = (Document)vsDTE.ActiveDocument;
//var window =  (Window)document.Windows.first();           
var textSelection  = (TextSelection)vsDTE.ActiveDocument.Selection;
var selectedLine = 1;
20.loop(100,()=>{
                    textSelection.GotoLine(selectedLine++);
                    textSelection.SelectLine();
                });
return textSelection;

этот код делает небольшую анимацию, где выделено 20 строк (с интервалом 100 мс)

правильный wingrep командная строка syntax заставить a new instance и перейти к номеру строки:

"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" $F /command "edit.goto $L"

заменить studio version number С правильной версией для вашей установки.

я собирался задать этот вопрос, потому что когда вы получаете "желтый экран смерти" при отладке веб-приложения, вы хотите быстро перейти к файлу и строке, которую он дает вам в stacktrace, например:

[ContractException: Precondition failed: session != null]
   System.Diagnostics.Contracts.__ContractsRuntime.TriggerFailure(ContractFailureKind kind, String msg, String userMessage, String conditionTxt, Exception inner) in C:\_svn\IntegratedAdaptationsSystem\Source\IntegratedAdaptationsSystem\IAS_UI\Controllers\CustomErrorsPageController.cs:0
   System.Diagnostics.Contracts.__ContractsRuntime.ReportFailure(ContractFailureKind kind, String msg, String conditionTxt, Exception inner) in C:\_svn\IntegratedAdaptationsSystem\Source\IntegratedAdaptationsSystem\IAS_UI\Controllers\CustomErrorsPageController.cs:0
   System.Diagnostics.Contracts.__ContractsRuntime.Requires(Boolean condition, String msg, String conditionTxt) in C:\_svn\IntegratedAdaptationsSystem\Source\IntegratedAdaptationsSystem\IAS_UI\Controllers\CustomErrorsPageController.cs:0
   IAS_UI.Web.IAS_Session..ctor(HttpSessionStateBase session) in C:\_svn\IntegratedAdaptationsSystem\Source\IntegratedAdaptationsSystem\IAS_UI\Web\IAS_Session.cs:15
   IAS_UI.Controllers.ServiceUserController..ctor() in C:\_svn\IntegratedAdaptationsSystem\Source\IntegratedAdaptationsSystem\IAS_UI\Controllers\ServiceUserController.cs:41

скажем, я хочу перейти к ServiceUserController.cs в строке 41. Обычно я открывал Visual Studio и делал это вручную, но затем я написал небольшой скрипт Autohotkey, который это делает.

открыть его, вы выделите имя файла и номер строки, например, ServiceUserController.cs:41 и после этого нажмите ярлык Alt + v. Вот его код:

$!v::
if (NOT ProcessExists("devenv.exe"))
{
    MsgBox, % "Visual Studio is not loaded"
}
else
{
    IfWinExist, Microsoft Visual Studio
    {
        ToolTip, Opening Visual Studio...
        c := GetClip()

        if (NOT c) {
            MsgBox, % "No text selected"
        }
        else 
        {
            WinActivate ; now activate visual studio
            Sleep, 50
            ; for now assume that there is only one instance of visual studio - handling of multiple instances comes in later

            arr := StringSplitF(c, ":")

            if (arr.MaxIndex() <> 2) {
                MsgBox, % "Text: '" . c . "' is invalid."
            }
            else {
                fileName := arr[1]
                lineNumber := arr[2]

                ; give focus to the "Find" box
                SendInput, ^d 

                ; delete the contents of the "Find" box
                SendInput, {Home}
                SendInput, +{End}
                SendInput, {Delete}

                ; input *** >of FILENAME *** into the "Find" box
                SendInput, >of{Space}
                SendInput, % fileName

                ; select the first entry in the drop down list
                SendInput, {Down}
                SendInput, {Enter}

                ; lineNumber := 12 remove later

                ; open the go to line dialog
                SendInput, ^g
                Sleep, 20

                ; send the file number and press enter
                SendInput, % lineNumber
                SendInput {Enter}
            }
        }    
        ToolTip
    }
}
return

вы хотите вставить следующие "служебные функции" перед ним:

GetClip()
{
    ClipSaved := ClipboardAll
    Clipboard=
    Sleep, 30
    Send ^c
    ClipWait, 2
    Sleep, 30
    Gc := Clipboard
    Clipboard := ClipSaved
    ClipSaved=

    return Gc
}

ProcessExists(procName)
{
    Process, Exist, %procName%

    return (ErrorLevel != 0)
}

StringSplitF(str, delimeters)
{
    Arr := Object()

    Loop, parse, str, %delimeters%,
    {
        Arr.Insert(A_LoopField)
    }

    return Arr
}

использование этой команды работает для меня, пока Visual Studio еще не открыта. "C:\Program файлы (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.EXE-файл" / "правка" "ABSOLUTEFILEPATH_FILENAME.ЦПП" /команды "изменить.Гото 164"

Если он уже открыт, то иногда он работает и переходит на правильную линию, но потом он просто перестает работать, и я никогда не понимал, почему. Похоже, Microsoft знает об этой проблеме, но сказал, что они "не исправят" его, если больше людей не жалуются. Так если это все еще проблема, я бы предложил комментировать здесь:https://connect.microsoft.com/VisualStudio/Feedback/Details/1128717

Comments

    Ничего не найдено.