[ACCEPTED]-Open a file in Visual Studio at a specific line number-command-line

Accepted answer
Score: 31

With VS2008 SP1, you can use the following 2 command line to open a file at a specific 1 line in an existing instance :

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

Source

Score: 29

Elaborating on Harold question and answer, I 6 adapted the C++ solution (that I first adopted) to 5 C#. It is much simpler (that is my first 4 C# program!). One just need to create a 3 project, add references to "envDTE" and 2 "envDTE80" and drop the following code:

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

One 1 then just calls openStudioFileLine path_to_file numberOfLine.

Hope that may help !

Score: 14

Based on reder answer I have published repository with source, here is binary(.net2.0)

I also 2 add support for multiple VS versions

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 

Example 1 using from GrepWin:

VisualStudioFileOpenTool.exe 12 %path% %line%
Score: 4

Pretty old thread, but it got me started 5 so here's another example. This AutoHotkey function 4 opens a file, and puts the cursor on a particular 3 rowand column.

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

Call with:

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

You could translate 2 it pretty much line by line to VBScript 1 or JScript.

Score: 3

Here is Python variation of Harold's solution:

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)

It 1 shows how to go to specified line + column.

Score: 3

Here is VBS variation of Harold's solution: link to .vbs script.

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

Windows 2 supports VBScript natively - no need for 1 compilation or any additional interpreters.

Score: 3

These C# dependencies on project references 3 are completely unecessary. Indeed much of 2 the code here is overly verbose. All you 1 need is this.

using System.Reflection;
using System.Runtime.InteropServices;

private static void OpenFileAtLine(string file, int line) {
    object vs = Marshal.GetActiveObject("VisualStudio.DTE");
    object ops = vs.GetType().InvokeMember("ItemOperations", BindingFlags.GetProperty, null, vs, null);
    object window = ops.GetType().InvokeMember("OpenFile", BindingFlags.InvokeMethod, null, ops, new object[] { file });
    object selection = window.GetType().InvokeMember("Selection", BindingFlags.GetProperty, null, window, null);
    selection.GetType().InvokeMember("GotoLine", BindingFlags.InvokeMethod, null, selection, new object[] { line, true });
}

Simples eh?

Score: 2

This is my working C# solution for Visual Studio 2017 (15.9.7)

For other versions of VS just change the 1 version number (i.e. "VisualStudio.DTE.14.0")

todo: Add Reference->Search 'envdte'->Check Checkbox for envdte->Click OK

using EnvDTE;        

private static void OpenFileAtLine(string file, int line)
{
    DTE dte = (DTE)  Marshal.GetActiveObject("VisualStudio.DTE.15.0");
    dte.MainWindow.Visible = true;
    dte.ExecuteCommand("File.OpenFile", file);
    dte.ExecuteCommand("Edit.GoTo", line.ToString());
}
Score: 1

For reference here is the ENVDE written 4 in C# (using O2 Platform inside VisualStudio to get 3 a reference to the live DTE object)

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;

This 2 code does a little animation where 20 lines 1 are selected (with a 100ms interval)

Score: 1

The correct wingrep command line syntax to force a new instance and 2 jump to a line number is:

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

Replace the studio version number with 1 the correct version for your setup.

Score: 1

The version posted by @Mungo64 worked for 7 me, but of course the version number is 6 always changing, so I made a version that 5 automatically searches until we find it.

Add 4 Reference->Search 'envdte'->Check Checkbox 3 for envdte->Click OK

//using EnvDTE; //I 2 didn't use the using directive as it causes 1 ambiguity in another module I'm using.

private static void OpenFileAtLine(string file, int line)
{
    //The number needs to be rolled to the next version each time a new version of visual studio is used... 
    EnvDTE.DTE dte = null;


    for (int i = 25; i > 8; i--) {
        try
        {
            dte = (EnvDTE.DTE)Marshal.GetActiveObject("VisualStudio.DTE." + i.ToString() + ".0");
        }
        catch (Exception ex)
        {
            //don't care... just keep bashing head against wall until success
        }
    }

    //the following line works fine for visual studio 2019:
    //EnvDTE.DTE dte = (EnvDTE.DTE)Marshal.GetActiveObject("VisualStudio.DTE.16.0");
    dte.MainWindow.Visible = true;
    dte.ExecuteCommand("File.OpenFile", file);
    dte.ExecuteCommand("Edit.GoTo", line.ToString());
}
Score: 0

I can't figure out a way to do this with 8 straight command-line options. It looks 7 like you will have to write a macro for 6 it. Supposedly, you can invoke them like 5 so.

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

So, you can probably create a macro that 4 takes a filename and a line number, then 3 opens the file and jumps to the proper place. But, I 2 don't know that you can specify a same-instance 1 flag somewhere, or not.

Score: 0

I was about to ask this question because 13 when you get the "yellow screen of death" when 12 debugging a web application, you want to 11 quickly go to the file and line that it 10 gives you in the stacktrace e.g:

[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

Say I want 9 to go to ServiceUserController.cs at line 8 41. Usually I would open Visual Studio 7 and do it manually but then I wrote a little 6 Autohotkey script which does it.

To open 5 it, you will highlight the filename and 4 line number e.g. ServiceUserController.cs:41 and thereafter press your 3 shortcut Alt + v. Here is the code for it:

$!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

You 2 will want to paste the following "utility 1 functions" before it:

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
}
Score: 0

Using this command works for me, as long 11 as Visual Studio is NOT open already. "C:\Program 10 Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" /edit 9 "ABSOLUTEFILEPATH_FILENAME.CPP" /command 8 "Edit.GoTo 164"

If it is already 7 open, then sometimes it works and goes to 6 the right line, but then it just stops working 5 and I have never figured out why. Looks 4 like Microsoft is aware of the issue but 3 have said they "Will Not Fix" it, unless 2 more people complain. So if it's still an 1 issue I'd suggest commenting here: https://connect.microsoft.com/VisualStudio/Feedback/Details/1128717

Score: 0

Slightly simplified version of the answer from OnceUponATimeInTheWest:

using System.Runtime.InteropServices;

private static void OpenFileAtLine(string file, int line) {
    dynamic vs = Marshal.GetActiveObject("VisualStudio.DTE");
    dynamic window = vs.ItemOperations.OpenFile(path);
    window.Selection.GotoLine(line, true);
}

It uses 2 dynamics instead of Reflection to make the code 1 a bit shorter and more readable.

More Related questions