Hi
I have this problem that I have been trying to solve for
few days but now I have almost given up.
The problem is this:
I have developed a MMC Snap-in DLL in C# such that all
the MMC COM-interfaces are redefined on .Net-side and
following attributes are given to each interface:
[ ComImport,
InterfaceType
(ComInterfaceType.InterfaceIsIUnknown),
Guid("955AB28A-5218-11D0-A985-00C04FD8D565") ]
The C# MMC snapin implements IComponent and
IComponentData interfaces so that when MMC.exe executes,
it can recognize this C# DLL as a COM Snap-in DLL and
loads and displays it correctly in Snap-in console's left
pane.
IComponentData has an interface-method named Initialize()
that is implemented by MySnapin class and called by MMC
at start-up. Inside Initialize(object pUnknown), I
initialize an instance member (say, myObject) of the
MySnapin class with the object passed by MMC to the
Initialize(..) method during start-up. This object is
saved (as per MSDN documentation) so that it can be
reused later-on to get IConsoleNamespace2 or any other
MMC supported interfaces by simple casting. And this
casting merely calls QueryInterface() to get the
particular interface to which it is casted.
And here is the problem. When I access this saved object
myObject (by casting it to IConsoleNamespace2) from
anywhere within MMC-created-Thread (that is the thread
that loads the snapin itself), it works fine.
However, when I create a Timer(System.Threading.Timer or
System.Timers.Timer) inside MySnapin class and I access
myObject (by casting it to IConsoleNamespace2) within the
timer-callback method--I get an exception with the
following message:
QueryInterface for interface IConsoleNamespace2 failed.
Things I have tried so far but have not worked:
1) When I WriteLine() ApartmentState for MMC main thread,
it gives me STA inside Initialize(). So I thought MMC is
running in STA.
2) When I WriteLine() ApartmentState for Timer callback
method, that thread gives me MTA which is okay as all
Timer callbacks are using Threadpool threads and these
are MTA by nature.
3) So with an assumption that it is an Apartment-
mismatch, I took out Timer from mySnapin code and created
a Thread and specifically set the apartment state to STA,
but still the Thread-method gives the same error when it
accesses the myobject. It did not work forcing me to
think that it is not an apartment issue.
4) As per my needs, I want to to use this solution with
timer.
Any help would be really appreciated. U can write to me
at nmkmurty@foxboro.com if you want any more
clarifications regarind this problem.
Thanks
Raja
Mattias Sj?gren - 02 Oct 2003 22:17 GMT
Raja,
The easiest solution would be to ensure that all your calls on the COM
object are made from the STA thread where your object was created.
Could you use the Winforms Timer instead? Or in some other way notify
the main thread that the timer has fired?
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Raja - 02 Oct 2003 23:16 GMT
Thanks Mattias for the reply.
But the problem is that the main thread is MMC's thread.
And there is no way to send notifies to it. Or I dont
know how to do it.
Also, I can not do something like setting up a loop in
side MMC main-thread wherein it checks for a .Net boolean
that I set to true from my own thread (this is STA
thread) which the loop in main thread can test and run
the some method on COM object that I intend to run from
my-own-thread/Timer Callback.
Another question is Timer uses .Net Threadpool threads
that are, I think inherently MTA, I do not know if that
is a problem too.
But when I tested the Timer or my own STA thread: in both
cases I got the same exception: QueryInterface failed.
Any more insight will be appreciated.
Raja
>-----Original Message-----
>Raja,
[quoted text clipped - 5 lines]
>
>Mattias
Mattias Sj?gren - 04 Oct 2003 22:19 GMT
>But the problem is that the main thread is MMC's thread.
>And there is no way to send notifies to it. Or I dont
>know how to do it.
If you have any UI on the thread (any object derived from Control) you
can call Control.Invoke to execute a method on that thread.
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Raja - 08 Oct 2003 18:10 GMT
Thanks Mattias.
That worked.
>-----Original Message-----
>
[quoted text clipped - 6 lines]
>
>Mattias