У меня есть утилита (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;
}