2008-12-08 24 views
50

Tôi có một tiện ích (grep) cung cấp cho tôi danh sách tên tệp và số dòng. Sau khi tôi đã xác định rằng devenv là chương trình chính xác để mở một tệp, tôi muốn đảm bảo rằng nó được mở ở số dòng được chỉ định. Trong emacs, điều này sẽ là:Mở một tệp trong Visual Studio tại một số dòng cụ thể

emacs +140 filename.c 

Tôi không tìm thấy gì giống như thế này cho Visual Studio (devenv). Gần nhất tôi đã tìm thấy là:

devenv /Command "Edit.Goto 140" filename.c 

Tuy nhiên, điều này tạo ra một bản sao riêng biệt cho từng tệp như vậy. Tôi thà có cái gì đó sử dụng một ví dụ hiện có.

Những biến thể tái sử dụng một devenv hiện có, nhưng không đi vào dòng chỉ:

devenv /Command "Edit.Goto 140" /Edit filename.c 
devenv /Command /Edit filename.c "Edit.Goto 140" 

Tôi nghĩ rằng việc sử dụng nhiều "/ Command" lý lẽ có thể làm điều đó, nhưng tôi có lẽ không có một trong những quyền bởi vì tôi hoặc là có được lỗi hoặc không có phản ứng nào cả (ngoài việc mở một devenv trống).

Tôi có thể viết một macro đặc biệt cho devenv, nhưng tôi muốn tiện ích này được sử dụng bởi những người khác không có macro đó. Và tôi không rõ về cách gọi macro đó bằng tùy chọn "/ Lệnh".

Bất kỳ ý tưởng nào?


Vâng, có vẻ như không có cách nào để làm điều này như tôi muốn. Vì có vẻ như tôi sẽ cần có mã chuyên dụng để khởi động Visual Studio, tôi đã quyết định sử dụng EnvDTE như hình dưới đây. Hy vọng rằng điều này sẽ giúp người khác.

#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

Tuyệt vời. Vì vậy, bạn gọi điều này với "devenv/lệnh Macros.MyMacros.visual_studio_open_file myFile someLineNumber"? – EndangeredMassa

+0

Không, đây chỉ là mã để mở một tệp với phiên bản hiện tại của devenv. Ý tưởng là nếu tôi phải có mã chuyên biệt để mở tệp, đây là mã đó. Xin lỗi tôi đã không liên hệ lại với bạn trước đây, tôi vừa mới nhận thấy nhận xét của bạn. –

+3

Tôi tự hỏi nếu có ai có một cách sạch hơn để làm điều này như của VS 2010? –

Trả lời

0

Tôi không thể tìm ra cách để thực hiện điều này bằng các tùy chọn dòng lệnh thẳng. Có vẻ như bạn sẽ phải viết một macro cho nó. Giả sử, bạn có thể gọi chúng như vậy.

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

Vì vậy, bạn có thể tạo macro có tên tệp và số dòng, sau đó mở tệp và chuyển đến vị trí thích hợp. Nhưng, tôi không biết rằng bạn có thể chỉ định một cờ giống nhau ở đâu đó, hay không.

+5

Điều này không thực sự giải quyết vấn đề, bởi vì devenv/lệnh bắt đầu một thể hiện mới –

+0

Không phải ở tất cả các giải pháp. Xem câu trả lời đúng bên dưới, với một bài đăng từ reder !! –

29

Với VS2008 SP1, bạn có thể sử dụng dòng lệnh sau để mở một tập tin tại một dòng cụ thể trong một thể hiện:

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

Source

+2

Điều này cũng hoạt động với VS2010. –

+7

Tôi đã thử điều này với không có trường hợp chạy và nó làm việc - VS2008 bắt đầu lên, mở tập tin, và đi đến dòng được chỉ định. Sau đó tôi đã thử nó trên một tập tin khác nhau (với VS2008 vẫn chạy) và nó mở tập tin nhưng vẫn ở dòng 1. Bạn cho rằng khác nhau giữa các thiết lập của chúng tôi là gì? –

+0

Tôi có thiết lập này trong Vim, và nó hoạt động một trong mười lần. VS2010 –

1

Để tham khảo ở đây là ENVDE viết bằng C# (sử dụng O2 Platform bên trong VisualStudio để tham chiếu đến đối tượng DTE trực tiếp)

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; 

Mã này thực hiện hoạt ảnh nhỏ, trong đó 20 dòng được chọn (với khoảng 100ms)

24

Làm quen với câu hỏi và câu trả lời Harold, tôi đã điều chỉnh giải pháp C++ (lần đầu tiên tôi áp dụng) thành C#. Nó đơn giản hơn nhiều (đó là chương trình C# đầu tiên của tôi!).Một chỉ cần tạo một dự án, thêm tài liệu tham khảo để "envDTE" và "envDTE80" và thả các đoạn mã sau:

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

Một sau đó chỉ cần gọi openStudioFileLine path_to_file numberOfLine.

Hy vọng điều đó có thể hữu ích!

+0

Tuyệt vời! Tôi đã phải thiết lập "VisualStudio.DTE.9.0" để có được nó làm việc (nó ném cho tôi một COMException với tin nhắn MK_E_UNAVAILABLE khác) –

+0

Có lẽ bạn sẽ thích ứng với mã của bạn để mở tập tin mà không có pathname đó là một phần của một dự án mở được khấu trừ từ dữ liệu dự án)? Và bởi đầu vào sau: FILENAME: LINE_NUM. Định dạng này được sử dụng rộng rãi trong thế giới Unix. Lý tưởng nhất, cần có một lệnh tương tác, như Ctrl + G nhảy tới LINE_NUM, nhưng nó cũng sẽ chuyển sang tệp khác nếu phần "FILENAME:" được cung cấp – midenok

12

Dựa trên reder câu trả lời tôi đã xuất bản repository with source, here is binary(.net2.0)

Tôi cũng hỗ trợ thêm cho nhiều phiên bản 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 

Ví dụ sử dụng từ grepWin:

VisualStudioFileOpenTool.exe 12 %path% %line% 
+0

Bước đẹp làm cho nó hoạt động trên nhiều phiên bản và được lưu trữ trên github. Kỳ lạ thay, nó hoạt động nhưng không phải trong những trường hợp thú vị. Nó hoạt động khi chạy từ trình gỡ rối, không phải từ dòng lệnh hoặc FxCop. VS2010, Win7. –

+0

Bạn được chào đón để làm cho nó tốt hơn! :) – diimdeep

+1

Cảm ơn rất nhiều. Trong các ứng dụng Qt của tôi, tôi có một trình ghi nhật ký ghi lại tập tin nguồn/số dòng của mỗi mục nhập nhật ký. Với mã này tôi có thể thêm một nút trên widget logger để nhảy vào dòng trong Visual Studio .. – drescherjm

0

Tôi đang định hỏi câu hỏi này bởi vì khi bạn nhận được "màn hình màu vàng của cái chết" khi gỡ lỗi một ứng dụng web, bạn muốn quickl y đi đến các tập tin và dòng mà nó mang lại cho bạn trong stacktrace ví dụ:

[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 

Nói rằng tôi muốn đi đến ServiceUserController.cs tại dòng 41. Thông thường tôi sẽ mở Visual Studio và làm điều đó bằng tay nhưng sau đó tôi đã viết một kịch bản Autohotkey nhỏ mà nó.

Để mở, bạn sẽ làm nổi bật tên tệp và số dòng, ví dụ: ServiceUserController.cs:41 và sau đó nhấn phím tắt Alt + v. Đây là mã cho nó:

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

Bạn sẽ muốn dán "chức năng tiện ích" sau đây trước khi nó: chủ đề

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

Khá cũ, nhưng nó đã cho tôi bắt đầu vì vậy đây là một ví dụ khác. Chức năng AutoHotkey này sẽ mở một tệp và đặt con trỏ lên một hàng và cột cụ thể.

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

Gọi với:

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

Bạn có thể dịch nó khá nhiều từng dòng để VBScript hay JScript.

2

Đây là Python biến thể của giải pháp Harold:

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) 

Nó cho thấy làm thế nào để đi đến dòng quy định + cột.

1

Các đúng wingrep dòng lệnh syntax để buộc một new instance và nhảy đến một số dòng là:

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

Thay studio version number với phiên bản chính xác cho thiết lập của bạn.

3

Dưới đây là biến thể VBS của giải pháp Harold: link to .vbs script.

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

Windows hỗ trợ VBScript nguyên bản - không cần biên dịch hoặc bất kỳ thông dịch viên bổ sung nào.

+0

Tôi cố gắng mở một tập tin và tìm một từ khóa. 'dte.ExecuteCommand" Edit.Find "," ID = "" label1 "" "' không hoạt động như VS nói "Văn bản được chỉ định sau không tìm thấy: ID = label1". Có vẻ như dấu ngoặc kép bị nuốt chửng. Bạn có biết tại sao? – Gqqnbig

+0

@LoveRight Tôi không chắc bạn đang đề cập đến điều gì. Tập lệnh trên liên kết không có bất kỳ "ExecuteCommand" nào. –

0

Sử dụng lệnh này làm việc cho tôi, miễn là Visual Studio KHÔNG được mở. "C: \ Program Files (x86) \ Microsoft Visual Studio 14.0 \ Common7 \ IDE \ devenv.exe"/chỉnh sửa "ABSOLUTEFILEPATH_FILENAME.CPP"/lệnh "Edit.GoTo 164"

Nếu nó đã được mở, sau đó đôi khi nó hoạt động và đi đúng hướng, nhưng sau đó nó ngừng hoạt động và tôi chưa bao giờ tìm ra lý do. Có vẻ như Microsoft nhận thức được vấn đề nhưng đã nói rằng họ "Sẽ không sửa" nó, trừ khi có nhiều người phàn nàn hơn. Vì vậy, nếu nó vẫn là một vấn đề tôi muốn đề nghị bình luận ở đây: https://connect.microsoft.com/VisualStudio/Feedback/Details/1128717

Các vấn đề liên quan