60 Stimmen

Öffnen einer Datei in Visual Studio an einer bestimmten Zeilennummer

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;
}

31voto

Fouré Olivier Punkte 319

Mit VS2008 SP1 können Sie die folgende Befehlszeile verwenden, um eine Datei an einer bestimmten Zeile in einer bestehenden Instanz zu öffnen:

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

Quelle

29voto

reder Punkte 1088

Bei der Ausarbeitung der Frage und Antwort von Harold habe ich die C++-Lösung (die ich zuerst übernommen habe) an C# angepasst. Es ist viel einfacher (das ist mein erstes C#-Programm!). Man muss nur ein Projekt erstellen, Verweise auf "envDTE" und "envDTE80" hinzufügen und den folgenden Code einfügen:

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);      
            }
        }
    }
}

Man ruft dann einfach openStudioFileLine path_to_file numberOfLine .

Ich hoffe, das hilft!

14voto

diimdeep Punkte 1087

Basierend auf reder Antwort habe ich veröffentlicht Repository mit Quelle , hier ist binär(.net2.0)

Ich füge auch Unterstützung für mehrere VS-Versionen hinzu

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 

Beispiel mit GrepWin:

VisualStudioFileOpenTool.exe 12 %path% %line%

4voto

Wade Hatler Punkte 1715

Das Thema ist zwar schon ziemlich alt, aber ich habe damit angefangen, also hier ein weiteres Beispiel. Diese AutoHotkey öffnet eine Datei und setzt den Cursor auf eine bestimmte Zeile oder Spalte.

; 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)
}

Rufen Sie mit an:

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

Sie können es ziemlich genau Zeile für Zeile in VBScript oder JScript übersetzen.

3voto

Evgeny Panasyuk Punkte 8906

Hier ist die Python-Variante von Harolds Lösung:

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)

Sie zeigt, wie man zu einer bestimmten Zeile und Spalte gelangt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X