Как я могу программно запустить визуальную студию и отправить ее в определенный файл / строку?

У меня есть хороший аккуратный способ захвата необработанных исключений, который я отображать для моих пользователей и (необязательно) получать по электронной почте мне. Обычно они выглядят примерно так:

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& 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)

Можно ли запустить Visual Studio и открыть c:\projects\myapp\somelibrary.h в строке, вызывающей нарушение, и если да, то как?

Я также хотел бы сделать это из электронного письма (html), которое я сгенерировал, если это возможно?


person Jon Cage    schedule 25.06.2010    source источник
comment
Я уверен, что вы можете использовать некоторые средства автоматизации или даже макрос, но я понятия не имею, как это сделать.   -  person leppie    schedule 25.06.2010
comment
Вам лучше попробовать это в реальных условиях развертывания. У вас не будет номеров строк.   -  person Hans Passant    schedule 25.06.2010
comment
@Hans Passant: он может отправить трассировку стека по почте и показать пользователю удобное сообщение.   -  person egrunin    schedule 25.06.2010
comment
@egrunin: понял, что сработает. Но номеров строк у него не будет, что должно существенно повлиять на вопрос.   -  person Hans Passant    schedule 25.06.2010
comment
Полезно знать Ганса. Есть ли способ сохранить информацию о номере строки или это только при запуске из Visual Studio?   -  person Jon Cage    schedule 25.06.2010
comment
Вы можете получить их, отправив файлы .pdb вместе с вашей программой. Не то чтобы это реальное исправление, оптимизатор кода перестраивает код, делает номера строк ненадежными.   -  person Hans Passant    schedule 25.06.2010


Ответы (2)


Вы можете автоматизировать Visual Studio, используя, например, 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)

Сохраните это как say debugger.vbs и запустите, передав имя файла и номер строки в качестве аргументов командной строки:

debugger.vbs c:\dev\my_file.cpp 42
person jon-hanson    schedule 25.06.2010

поскольку ваш вопрос помечен как C ++, вот некоторый код на этом языке для достижения этой цели; в основном тот же принцип, что и ответ Джона, но больше текста ..

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 ) ) );
}
person stijn    schedule 25.06.2010