Откройте файл в 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 punk; result = ::GetActiveObject(clsid, NULL, &punk); if (FAILED(result)) return false; CComPtr DTE; DTE = punk; CComPtr item_ops; result = DTE->get_ItemOperations(&item_ops); if (FAILED(result)) return false; CComBSTR bstrFileName(filename); CComBSTR bstrKind(EnvDTE::vsViewKindTextView); CComPtr window; result = item_ops->OpenFile(bstrFileName, bstrKind, &window); if (FAILED(result)) return false; CComPtr doc; result = DTE->get_ActiveDocument(&doc); if (FAILED(result)) return false; CComPtr selection_dispatch; result = doc->get_Selection(&selection_dispatch); if (FAILED(result)) return false; CComPtr selection; result = selection_dispatch->QueryInterface(&selection); if (FAILED(result)) return false; result = selection->GotoLine(line, TRUE); if (FAILED(result)) return false; return true; } 

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

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

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

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

 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 .

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

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

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

 usage:    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 открывает файл и помещает курсор в конкретный столбец rowand.

 ; 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 командной строки wingrep чтобы заставить new instance и перейти к номеру строки:

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

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

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

 [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 Files (x86) \ Microsoft Visual Studio 14.0 \ Common7 \ IDE \ devenv.exe” / edit “ABSOLUTEFILEPATH_FILENAME.CPP” / команда “Edit.GoTo 164”

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

  • Поиск аргумента Аргумент аргумента командной строки для .NET
  • R, передающая имя файла сценарию в аргументах (Windows)
  • Разделить строку, содержащую параметры командной строки, в строку в C #
  • Как установить компоненты cygwin из командной строки?
  • Печать rpath исполняемого файла в OSX
  • Как использовать символы Unicode в командной строке Windows?
  • Как проанализировать аргументы командной строки в Bash?
  • Инструмент командной строки для сброса версии Windows DLL?
  • Xcode «Build and Archive» из командной строки
  • Grep и Sed Equivalent для обработки командной строки XML
  • Как запустить эмулятор Android из командной строки?
  • Interesting Posts

    Maven: добавьте зависимость к банке относительным путем

    Как подключить устройство к Eclipse?

    Как настроить тип входного диапазона HTML5, используя CSS?

    Как найти утечки памяти из собственного кода в android

    Любое расширение хром, которое вращает изображение на странице?

    Многомерный std :: array

    Как определить, запускаю ли я 32-битную или 64-битную установку Ubuntu

    У палки RAM есть несколько плохих блоков. Есть ли способ отключить их или выделить плохие блоки, чтобы другие программы не могли их использовать?

    count (*) и count (column_name), что такое diff?

    Что значит для функции C ++ быть встроенным?

    Экранное меню Windows 10 Power + WinX и контекстное меню

    Как получить текущий аромат в gradleле

    Как импортировать XML-файл в таблицу базы данных MySQL, используя XML_LOAD (); функция

    Как изменить цвет текста и значков для tabBarItems в iOS 7?

    Можно ли установить стиль отображения строк в Microsoft Word?

    Давайте будем гением компьютера.