COM Exception: EnvDTE.Solution.Open(String FileName) - TFS Build Agent Execution

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
I have the following interface and class defined below for handling COM Retries:
<pre class="prettyprint using System;
using System.Runtime.InteropServices;
namespace DteOperations
{
[ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface IOleMessageFilter
{
[PreserveSig]
int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo);
[PreserveSig]
int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType);
[PreserveSig]
int MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType);
}
}[/code]
<br/>

<pre class="prettyprint namespace DteOperations
{
public class MessageFilter : IOleMessageFilter
{
public class MessageFilter : IOleMessageFilter
{
public static int Register()
{
IOleMessageFilter newFilter = new MessageFilter();
IOleMessageFilter oldFilter = null;
return NativeMethods.CoRegisterMessageFilter(newFilter, out oldFilter);
}
public static int Revoke()
{
IOleMessageFilter oldFilter = null;
return NativeMethods.CoRegisterMessageFilter(null, out oldFilter);
}
int IOleMessageFilter.HandleInComingCall(int dwCallType, System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr lpInterfaceInfo)
{
return (int)ServerCall.IsHandled;
}
int IOleMessageFilter.RetryRejectedCall(System.IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
{
if (dwRejectType == (int)ServerCall.RetryLater)
{
return 99;
}
return -1;
}
int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
{
System.Diagnostics.Debugger.Launch();
return (int)PendingMessage.WaitDefProcess;
}
}
}
}[/code]
I then have another class with a method that returns a Visual Studio 2010 Solution:
<pre class="prettyprint using EnvDTE;
using System;
using System.Runtime.InteropServices;
namespace DteOperations
{
public class DteHelper
{
public DteHelper()
{
Retries = 1;
}
public DteHelper(int retries)
{
Retries = retries;
}
private int _retries;
public int Retries
{
get
{
return _retries;
}
set
{
_retries = value;
}
}
public Solution RetrieveSolution(string solutionPath)
{
try
{
Solution solution = null;
for (int i = 0; i < Retries; i++)
{
try
{
MessageFilter.Register();
Type t = Type.GetTypeFromProgID("VisualStudio.DTE.10.0");
object obj = Activator.CreateInstance(t, true);
EnvDTE dte = (DTE)obj;
dte SuppressUI = true;
solution = dte.Solution;
if (File.Exists(solutionPath))
{
solution.Open(solutionPath);
}
else
{
throw new FileNotFoundException(string.Format(CultureInfo.CurrentCulture, "Solution file not found at {0}", Path.GetFullPath(solutionPath)));
}
}
catch (COMException e)
{
if (e.ErrorCode == (int)ServerCall.RetryLater)
{
continue;
}
else
{
MessageFilter.Revoke();
throw;
}
}
}
return solution;
}
catch
{
throw;
}
}
}
}[/code]
I instantiate the DteHelper class and call the RetrieveSolution method from a unit test in Visual Studio as follows:
<pre class="prettyprint new DteHelper(100).RetrieveSolution(@"C:SolutionPath");[/code]
When I run the unit test locally, the unit test passes. However, upon queueing and running the TFS build definition, when MSTest runs the unit test on the TFS Build Agent, the unit test fails with the following error:
<pre class="prettyprint One of the background threads threw exception:
System.Runtime.InteropServices.COMException (0x80030002): could not be found. (Exception from HRESULT: 0x80030002 (STG_E_FILENOTFOUND))
at EnvDTE._Solution.Open(String FileName)[/code]
The solution being opened is the same solution that the TFS Build Agent is compiling and running unit tests for. Could it be that because the TFS Build Agent is currently using the Visual Studio Solution that this error occurs? I do not experience this problem
when running locally though, even though the Visual Studio Solution is open.
Does anyone have an idea of how to solve this issue?
<br/>
<br/>

View the full article
 
Back
Top