How can I programmatically launch visual studio and send it to a specific file / line?
I have a nice tidy way of capturing unhandled exceptions which I display to my users and (optionally) get emailed to myself. They generally look something like this:
Uncaught exception encountered in MyApp (Version 1.1.0)!
Exception:
Object reference not set to an instance of an object.
Exception type:
System.NullReferenceException
Source:
MyApp
Stack trace:
at SomeLibrary.DoMoreStuff() in c:\projects\myapp\somelibrary.h:line 509
at SomeAlgothim.DoStuff() in c:\projects\myapp\somealgorithm.h:line 519
at MyApp.MainForm.ItemCheckedEventHandler(Object sender, ItemCheckedEventArgs e) in c:\projects\myapp\mainform.cpp:line 106
at System.Windows.Forms.ListView.OnItemChecked(ItemCheckedEventArgs e)
at System.Windows.Forms.ListView.WmReflectNotify(Message& m)
at System.Windows.Forms.ListView.WndProc(Message开发者_如何学C& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Is it possible to launch visual studio and have it open c:\projects\myapp\somelibrary.h
on the offending line and if so, how?
I'd also like to do this from the (html) email I generate if that's possible?
You can automate Visual Studio, using for example VBScript:
filename = Wscript.Arguments(0)
lineNo = Wscript.Arguments(1)
' Creates an instance of the Visual Studio IDE.
Set dte = CreateObject("VisualStudio.DTE")
' Make it visible and keep it open after we finish this script.
dte.MainWindow.Visible = True
dte.UserControl = True
' Open file and move to specified line.
dte.ItemOperations.OpenFile(filename)
dte.ActiveDocument.Selection.GotoLine (lineNo)
Save this as say debugger.vbs
and run it, passing the filename and line no as command line args:
debugger.vbs c:\dev\my_file.cpp 42
since your question is tagged C++, here's some code in that language to achieve this; basically the same principle as jon's answer, but more text..
bool OpenFileInVisualStudio( const char* psFile, const unsigned nLine )
{
CLSID clsid;
if( FAILED( ::CLSIDFromProgID( L"VisualStudio.DTE", &clsid ) ) )
return false;
CComPtr<IUnknown> punk;
if( FAILED( ::GetActiveObject( clsid, NULL, &punk ) ) )
return false;
CComPtr<EnvDTE::_DTE> DTE = punk;
CComPtr<EnvDTE::ItemOperations> item_ops;
if( FAILED( DTE->get_ItemOperations( &item_ops ) ) )
return false;
CComBSTR bstrFileName( psFile );
CComBSTR bstrKind( EnvDTE::vsViewKindTextView );
CComPtr<EnvDTE::Window> window;
if( FAILED( item_ops->OpenFile( bstrFileName, bstrKind, &window ) ) )
return false;
CComPtr<EnvDTE::Document> doc;
if( FAILED( DTE->get_ActiveDocument( &doc ) ) )
return false;
CComPtr<IDispatch> selection_dispatch;
if( FAILED( doc->get_Selection( &selection_dispatch ) ) )
return false;
CComPtr<EnvDTE::TextSelection> selection;
if( FAILED( selection_dispatch->QueryInterface( &selection ) ) )
return false;
return !FAILED( selection->GotoLine( Line, TRUE ) ) );
}
精彩评论