K
Konrad Anton
Hello all,
The following program (or rather NUnit test script) causes Visio 2007
Professional to crash with a
"Microsoft Office Visio has encountered a problem and needs to close.
We are sorry for the inconvenience." dialog (without meaningful error code).
The test script opens a Visio application, creates a new document and
posts a number of home-made IVBUndoUnit dummies on the undo stack.
After a random number of posted undo items (Test_newPage usually needs
28 to 30, but I've also seen 12; Test_noNewPage sometimes doesn't crash
at all, otherwise with varying number of items), the Visio crash dialog
appears, and NUnit reports a COMException about the RPC server not being
available (which is fair because it has just exited). The COMException's
stacktrace points to the line with the AddUndoUnit call.
I've disabled the add-in I'm developing by adding an early return
statement in the ThisAddIn_Startup method, so my event sinks should not
contribute to the problem.
This puzzles me. I've removed everything I consider dangerous, and I
still get a Visio crash. Any ideas?
Greetings
Konrad
//-----------------------------------------------------------------
using System;
using NUnit.Framework;
using Microsoft.Office.Interop.Visio;
using System.Diagnostics;
namespace VisioModeler.VisioAL.Impl.Test
{
[TestFixture]
public class TestIssueCrashWithCustomUndoUnits
{
protected Microsoft.Office.Interop.Visio.Application app;
[SetUp]
virtual public void SetUp()
{
app = new Microsoft.Office.Interop.Visio.Application();
}
[TearDown]
virtual public void TearDown()
{
foreach (Document doc in app.Documents)
{
app.AlertResponse = 7; // IDNO -- as answer to "Save?
Yes/No/Cancel"
doc.Close();
}
app.Quit();
}
[Test]
public void Test_newPage()
{
Document newDoc = app.Documents.AddEx("",
VisMeasurementSystem.visMSMetric, 0, 0);
Page page1 = newDoc.Pages.Add();
for (int i = 0; i < 50; ++i)
{
Debug.Print("AddUndoUnit {0}", i);
app.AddUndoUnit(new MinimalUndoUnit());
}
}
[Test]
public void Test_noNewPage()
{
Document newDoc = app.Documents.AddEx("",
VisMeasurementSystem.visMSMetric, 0, 0);
for (int i = 0; i < 50; ++i)
{
Debug.Print("AddUndoUnit {0}", i);
app.AddUndoUnit(new MinimalUndoUnit());
}
}
private class MinimalUndoUnit : IVBUndoUnit
{
public string Description { get { return "whatever."; } }
public void Do(IVBUndoManager pMgr) { }
public void OnNextAdd() { }
public int UnitSize { get { return 0; } }
public string UnitTypeCLSID { get { return string.Empty; } }
public int UnitTypeLong { get { return 0; } }
}
}
}
//-----------------------------------------------------------------
For readers unfamiliar with NUnit: the call sequence becomes
SetUp()
Test_newPage()
TearDown()
SetUp()
Test_noNewPage()
TearDown()
The following program (or rather NUnit test script) causes Visio 2007
Professional to crash with a
"Microsoft Office Visio has encountered a problem and needs to close.
We are sorry for the inconvenience." dialog (without meaningful error code).
The test script opens a Visio application, creates a new document and
posts a number of home-made IVBUndoUnit dummies on the undo stack.
After a random number of posted undo items (Test_newPage usually needs
28 to 30, but I've also seen 12; Test_noNewPage sometimes doesn't crash
at all, otherwise with varying number of items), the Visio crash dialog
appears, and NUnit reports a COMException about the RPC server not being
available (which is fair because it has just exited). The COMException's
stacktrace points to the line with the AddUndoUnit call.
I've disabled the add-in I'm developing by adding an early return
statement in the ThisAddIn_Startup method, so my event sinks should not
contribute to the problem.
This puzzles me. I've removed everything I consider dangerous, and I
still get a Visio crash. Any ideas?
Greetings
Konrad
//-----------------------------------------------------------------
using System;
using NUnit.Framework;
using Microsoft.Office.Interop.Visio;
using System.Diagnostics;
namespace VisioModeler.VisioAL.Impl.Test
{
[TestFixture]
public class TestIssueCrashWithCustomUndoUnits
{
protected Microsoft.Office.Interop.Visio.Application app;
[SetUp]
virtual public void SetUp()
{
app = new Microsoft.Office.Interop.Visio.Application();
}
[TearDown]
virtual public void TearDown()
{
foreach (Document doc in app.Documents)
{
app.AlertResponse = 7; // IDNO -- as answer to "Save?
Yes/No/Cancel"
doc.Close();
}
app.Quit();
}
[Test]
public void Test_newPage()
{
Document newDoc = app.Documents.AddEx("",
VisMeasurementSystem.visMSMetric, 0, 0);
Page page1 = newDoc.Pages.Add();
for (int i = 0; i < 50; ++i)
{
Debug.Print("AddUndoUnit {0}", i);
app.AddUndoUnit(new MinimalUndoUnit());
}
}
[Test]
public void Test_noNewPage()
{
Document newDoc = app.Documents.AddEx("",
VisMeasurementSystem.visMSMetric, 0, 0);
for (int i = 0; i < 50; ++i)
{
Debug.Print("AddUndoUnit {0}", i);
app.AddUndoUnit(new MinimalUndoUnit());
}
}
private class MinimalUndoUnit : IVBUndoUnit
{
public string Description { get { return "whatever."; } }
public void Do(IVBUndoManager pMgr) { }
public void OnNextAdd() { }
public int UnitSize { get { return 0; } }
public string UnitTypeCLSID { get { return string.Empty; } }
public int UnitTypeLong { get { return 0; } }
}
}
}
//-----------------------------------------------------------------
For readers unfamiliar with NUnit: the call sequence becomes
SetUp()
Test_newPage()
TearDown()
SetUp()
Test_noNewPage()
TearDown()