Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio 在Visual Studio中的特定行号处打开文件_Visual Studio_Command Line - Fatal编程技术网

Visual studio 在Visual Studio中的特定行号处打开文件

Visual studio 在Visual Studio中的特定行号处打开文件,visual-studio,command-line,Visual Studio,Command Line,我有一个实用程序(grep),它给我一个文件名列表和行号。在我确定devenv是打开文件的正确程序之后,我希望确保它在指定的行号处打开。在emacs中,这将是: emacs +140 filename.c 我在VisualStudio(devenv)中找不到类似的东西。我发现最接近的是: devenv /Command "Edit.Goto 140" filename.c 但是,这会为每个这样的文件创建一个单独的devenv实例。我更喜欢使用现有实例的东西 这些变体重复使用现有的devenv

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

emacs +140 filename.c
我在VisualStudio(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”选项调用该宏

有什么想法吗


嗯,似乎没有一种方法可以像我想的那样做到这一点。因为我需要有专门的代码来启动VisualStudio,所以我决定使用EnvDTE,如下所示。希望这能帮助其他人

#包括“stdafx.h”
//-----------------------------------------------------------------------
//这个密码是从你的电脑里偷来的http://benbuck.com/archives/13
//
//这是一个叫“BenBuck”的人的博客
//似乎没有任何信息。
//-----------------------------------------------------------------------
//进口环境
#杂注警告(禁用:4278)
#杂注警告(禁用:4146)
#导入“libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2”版本(“8.0”)lcid(“0”)原始接口仅命名为
#杂注警告(默认值:4146)
#杂注警告(默认值:4278)
bool visual_studio_open_文件(字符常量*文件名,无符号整数行)
{
HRESULT结果;
CLSID-CLSID;
结果=::CLSIDFromProgID(L“VisualStudio.DTE”,&clsid);
如果(失败(结果))
返回false;
朋克;
结果=::GetActiveObject(clsid、NULL和punk);
如果(失败(结果))
返回false;
首席数据传输工程师;
DTE=朋克;
C采购项目运作;
结果=DTE->get_ItemOperations(&item_ops);
如果(失败(结果))
返回false;
CCOMBSTRFILENAME(文件名);
ccombstrkind(EnvDTE::vsViewKindTextView);
CComPtr窗口;
结果=项操作->打开文件(bstrFileName、bstrKind和窗口);
如果(失败(结果))
返回false;
CComPtr文件;
结果=DTE->获取动态文档(&doc);
如果(失败(结果))
返回false;
承包商选择和调度;
结果=单据->获取所选内容(&Selection\u dispatch);
如果(失败(结果))
返回false;
买方选择;
结果=选择\发送->查询接口(&selection);
如果(失败(结果))
返回false;
结果=选择->GotoLine(行,真);
如果(失败(结果))
返回false;
返回true;
}

我想不出用直接命令行选项实现这一点的方法。看起来您必须为它编写一个宏。你可以这样调用它们

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

因此,您可能可以创建一个宏,该宏采用文件名和行号,然后打开文件并跳转到正确的位置。但是,我不知道您是否可以在某个位置指定相同的实例标志。

使用VS2008SP1,您可以使用以下命令行在现有实例中的特定行打开文件:

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

此处是用C#编写的ENVDE供参考(使用inside VisualStudio获取对live DTE对象的引用)


<代码>在20行被选择(100MS间隔)

的动画中,对哈罗德问题的答案和答案进行了修改,我将C++的解决方案(我首先采用的)修改为C。它要简单得多(这是我的第一个C#程序!)。只需创建一个项目,添加对“envDTE”和“envDTE80”的引用,并删除以下代码:

使用系统;
使用System.Collections.Generic;
使用系统文本;
命名空间openStudioFileLine
{
班级计划
{
[状态线程]
静态void Main(字符串[]参数)
{
尝试
{
字符串文件名=args[0];
int文件行;
int.TryParse(args[1],out文件行);
EnvDTE80.DTE2 DTE2;
dte2=(EnvDTE80.dte2)System.Runtime.InteropServices.Marshal.GetActiveObject(“VisualStudio.DTE”);
dte2.MainWindow.Activate();
windoww=dte2.ItemOperations.OpenFile(文件名为EnvDTE.Constants.vsViewKindTextView);
((EnvDTE.TextSelection)dte2.ActiveDocument.Selection).GotoLine(fileline,true);
}
捕获(例外e)
{          
控制台。写入(e.Message);
}
}
}
}
然后只需调用
openStudioFileLine path\u到\u file numberOfLine

希望这能有所帮助

根据我发表的答案

我还添加了对多个VS版本的支持

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 

我之所以要问这个问题,是因为当调试web应用程序时出现“死亡黄屏”时,您希望快速转到它在stacktrace中提供给您的文件和行,例如:

[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
假设我想转到第41行的ServiceUserController.cs。通常我会打开VisualStudio并手动执行,但随后我编写了一个自动热键脚本来执行此操作

要打开它,您将突出显示文件名和行号,例如
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

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

; 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)
}
致电:
$!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
}
; 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)
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)
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" $F /command "edit.goto $L"
open-in-msvs.vbs full-path-to-file line column
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 });
}
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());
}
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());
}