none
ComVisible .Net Assembly doesn't close process RRS feed

  • Question

  • I have created an assembly with a UserControl that is visible to COM and essentially host a WPF Element loaded via method SetControllo. Testing the control via TstCon32 or via my COM application, i notice that when i close the application, the UserControl seems to block the application shutdown sequence and i see TstCon32.exe in my task manager and i have to kill it. Where is my fault? I have pasted all the source code of this simple control. elementHost1 is a Wpf interoperability ElementHost.
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
        public interface IHost
        {
            void SetControllo(string value);
        }
    
        [ComVisible(true)]
        [ProgId("HostWPFControl.Host")]
        [ClassInterface(ClassInterfaceType.None)]
        [Guid("59F21D9D-6A1A-4e70-BD2D-42C1E64D7A47")]
        public partial class Host : UserControl, IHost
        {
            public Host()
            {
                InitializeComponent();
                this.elementHost1.Child = new TextBlock() { Text = "Container vuoto" };
            }
    
            public void SetControllo(string value)
            {
    
                    UIElement wpfelement = null; //code is eliminated... this is not the problem
                    this.elementHost1.Child = wpfelement;
                }
                catch (Exception ex)
                {
                    UIElement wpfelement = new TextBlock();
    
                    ((TextBlock)wpfelement).Text = ex.Message;    ((TextBlock)wpfelement).TextWrapping = TextWrapping.Wrap;
                    ((TextBlock)wpfelement).Width = 400;
                    this.elementHost1.Child = wpfelement;
                }
            }
    
            [ComRegisterFunction()]
            public static void RegisterClass(string key)
            {
                Trace.Write(String.Format("Registering DLL {0}", key));
                StringBuilder sb = new StringBuilder(key);
                sb.Replace(@"HKEY_CLASSES_ROOT\", "");
                RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
                RegistryKey ctrl = k.CreateSubKey("Control");
                ctrl.Close();
                RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
                inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
                inprocServer32.Close();
                k.Close();
            }
    
            [ComUnregisterFunction()]
            public static void UnregisterClass(string key)
            {
                Trace.Write(String.Format("Unregistering DLL {0}", key));
                StringBuilder sb = new StringBuilder(key);
                sb.Replace(@"HKEY_CLASSES_ROOT\", "");
                RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
                if (k == null)
                {
                    return;
                }
                k.DeleteSubKey("Control", false);
                RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
                inprocServer32.DeleteSubKey("CodeBase", false);
                inprocServer32.Close(); k.Close();
            }
        }
    

    Monday, August 24, 2009 1:31 PM

Answers