2008-12-08 109 views
50

我有一个实用程序(grep),它提供了一个文件名列表和一个行号。在确定devenv是打开文件的正确程序之后,我想确保它在指定的行号处打开。在emacs,这将是:在Visual Studio中打开一个特定行号的文件

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" 

我认为使用多个“/命令”参数可能做到这一点,但我可能不有正确的一个,因为我得到错误或根本没有回应(除了打开一个空的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; 
} 
+0

太棒了。那么,你是否用“devenv/command Macros.MyMacros.visual_studio_open_file myFile someLineNumber”来调用它? – EndangeredMassa 2008-12-12 14:55:38

+0

不,这只是用devenv的现有实例打开文件的代码。这个想法是,如果我必须有专门的代码来打开文件,这就是代码。 对不起,我以前没有回复你,我刚刚注意到你的评论。 – 2008-12-17 17:00:05

+3

我想知道是否有人有更清晰的方式来做到这一点VS 2010? – 2010-08-24 20:52:27

回答

0

我找不出一种方法来使用直接的命令行选项。它看起来像你将不得不为它写一个宏。据说,你可以像这样调用它们。

​​

所以,你也许可以创建一个宏,将文件名和行号,然后打开文件,并跳转到合适的位置。但是,我不知道你可以在某处指定同一实例标志,或者不指定。

+5

这实际上并没有解决问题,因为devenv /命令启动了一个新实例 – 2010-08-24 20:52:07

+0

根本不是解决方案。看到下面的正确答案,从reder的帖子! – 2012-09-18 13:54:11

29

随着VS2008 SP1,可以使用下面的命令行中现有的实例打开一个文件在特定行:

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

Source

+2

这也适用于VS2010。 – 2010-09-09 15:47:26

1

仅供参考这里是写在ENVDE C#(使用Visual Studio中的O2 Platform来获得对现场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行被选中(间隔100ms)

24

在Harold问题和答案上进行了详细阐述,我将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

希望可以帮助!

12

基于reder答案我已经发表repository with sourcehere is binary(.net2.0)

我还添加了多个VS版本

从GrepWin使用
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 

实例支持:

VisualStudioFileOpenTool.exe 12 %path% %line% 
0

我正要问这个问题是因为当你在调试Web应用程序时遇到“死亡的黄色屏幕”时,你想快速查看Ÿ去的文件和行,它给你的堆栈跟踪例如:

[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 
} 
3

很老的线程,但它让我开始,所以这里是另一个例子。这个AutoHotkey函数打开一个文件,并将光标放在特定的行和列上。

; 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翻译它几乎一致。

2

这里是哈罗德的解决方案的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) 

它显示了如何去指定的行+列。

1

正确wingrep命令行syntax强制new instance并跳转到一个行号:

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

与正确的版本为您安装更换studio version number

3

这是哈罗德解决方案的VBS变体:link to .vbs script

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

Windows本机支持VBScript - 无需编译或任何其他解释器。

0

只要Visual Studio尚未打开,使用此命令对我很有用。 “C:\ Program Files(x86)\ Microsoft Visual Studio 14.0 \ Common7 \ IDE \ devenv.exe”/编辑“ABSOLUTEFILEPATH_FILENAME.CPP”/ command“Edit.GoTo 164”

如果它已经打开,有时它工作并走向正确的路线,但之后它就停止工作,我从未想出原因。看起来微软已经意识到这个问题,但是他们表示他们“不会修复”它,除非有更多人抱怨。所以,如果它仍然是一个问题,我建议在这里评论:https://connect.microsoft.com/VisualStudio/Feedback/Details/1128717

相关问题