Ich habe ein Dienstprogramm (grep), das mir eine Liste von Dateinamen und Zeilennummern liefert. Nachdem ich festgestellt habe, dass devenv das richtige Programm zum Öffnen einer Datei ist, möchte ich sicherstellen, dass sie an der angegebenen Zeilennummer geöffnet wird. In emacs wäre dies der Fall:
emacs +140 filename.c
Ich habe nichts dergleichen für Visual Studio (devenv) gefunden. Das nächste, was ich gefunden habe, ist:
devenv /Command "Edit.Goto 140" filename.c
Dadurch wird jedoch für jede dieser Dateien eine eigene Instanz von devenv erzeugt. Ich würde lieber etwas haben, das eine bestehende Instanz verwendet.
Diese Varianten verwenden ein bestehendes devenv, gehen aber nicht bis zur angegebenen Zeile:
devenv /Command "Edit.Goto 140" /Edit filename.c
devenv /Command /Edit filename.c "Edit.Goto 140"
Ich dachte, dass die Verwendung mehrerer "/Command"-Argumente könnte es tun, aber ich habe wahrscheinlich nicht die richtige, weil ich entweder Fehler oder keine Antwort überhaupt (andere als das Öffnen eines leeren devenv) erhalten.
Ich könnte ein spezielles Makro für devenv schreiben, aber ich möchte, dass dieses Dienstprogramm auch von anderen verwendet werden kann, die dieses Makro nicht haben. Und mir ist nicht klar, wie ich dieses Makro mit der Option "/Command" aufrufen kann.
Irgendwelche Ideen?
Nun, es sieht nicht so aus, als gäbe es eine Möglichkeit, dies so zu tun, wie ich es wollte. Da es so aussieht, als bräuchte ich einen eigenen Code, um Visual Studio zu starten, habe ich mich entschieden, EnvDTE wie unten gezeigt zu verwenden. Ich hoffe, dass dies jemand anderem helfen wird.
#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;
}