/// <summary> /// PreMessageLoop is responsible for registering the COM class /// factories for the COM classes to be exposed from the server, and /// initializing the key member variables of the COM server (e.g. /// _nMainThreadID and _nLockCnt). /// </summary> private void PreMessageLoop() { // // Register the COM class factories. // //Guid clsidSimpleObj = new Guid(SimpleObject.ClassId); Guid clsid = new Guid(IID.VDServer); // Register the SimpleObject class object int hResult = COMNative.CoRegisterClassObject(ref clsid, new VDServerClassFactory(), CLSCTX.LOCAL_SERVER, REGCLS.SINGLEUSE | REGCLS.SUSPENDED, out _cookie); if (hResult != 0) { throw new ApplicationException("CoRegisterClassObject failed w/err 0x" + hResult.ToString("X")); } // Inform the SCM about all the registered classes, and begins // letting activation requests into the server process. hResult = COMNative.CoResumeClassObjects(); if (hResult != 0) { // Revoke the registration of SimpleObject on failure if (_cookie != 0) { COMNative.CoRevokeClassObject(_cookie); } // Revoke the registration of other classes // ... throw new ApplicationException("CoResumeClassObjects failed w/err 0x" + hResult.ToString("X")); } // Records the ID of the thread that runs the COM server so that // the server knows where to post the WM_QUIT message to exit the // message loop. _nMainThreadID = NativeMethod.GetCurrentThreadId(); // Records the count of the active COM objects in the server. // When _nLockCnt drops to zero, the server can be shut down. _nLockCnt = 0; // Start the GC timer to trigger GC every 5 seconds. _gcTimer = new Timer(new TimerCallback(GarbageCollect), null, 5000, 5000); }
/// <summary> /// PostMessageLoop is called to revoke the registration of the COM /// classes exposed from the server, and perform the cleanups. /// </summary> private void PostMessageLoop() { // Revoke the registration of COM classes if (_cookie != 0) { COMNative.CoRevokeClassObject(_cookie); } // Dispose the GC timer. if (_gcTimer != null) { _gcTimer.Dispose(); } // Wait for any threads to finish. Thread.Sleep(1000); }