Visual studio 在Visual Studio中的特定行号处打开文件
我有一个实用程序(grep),它给我一个文件名列表和行号。在我确定devenv是打开文件的正确程序之后,我希望确保它在指定的行号处打开。在emacs中,这将是: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
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());
}