Uninstall an Excel Add-In which was previously installed by adxregistrator

Add-in Express™ Support Service
That's what is more important than anything else

Uninstall an Excel Add-In which was previously installed by adxregistrator
Helps functions for modifying the registry 
Subscribe
fintools




Posts: 8
Joined: 2016-03-24
It appears that this.ExcelApp is null. Here is the result of the below code:

[22948] FinTools NET Debug: AddIn Name: FinToolsNET
[22948] FinTools NET Debug: Error=Object reference not set to an instance of an object.


        private void AddinModule_OnUnregister(object sender, EventArgs e)
        {

            try
            {
                System.Diagnostics.Debug.WriteLine("FinTools NET Debug: AddIn Name:  " + this.AddinName);

                string versionName = this.ExcelApp.ToString();
                System.Diagnostics.Debug.WriteLine("FinTools NET Debug: versionName: " + versionName);

                int length = versionName.IndexOf('.');
                System.Diagnostics.Debug.WriteLine("FinTools NET Debug: length: " + length.ToString());

                versionName = versionName.Substring(0, length);
                System.Diagnostics.Debug.WriteLine("FinTools NET Debug: versionName:= " + versionName);

                int versionNumber = int.Parse(versionName, System.Globalization.CultureInfo.GetCultureInfo("en-US"));
                System.Diagnostics.Debug.WriteLine("FinTools NET Debug: versionNumber: " + versionNumber.ToString());

                int bitness = IntPtr.Size;
                System.Diagnostics.Debug.WriteLine("FinTools NET Debug: bitness: " + bitness.ToString());

                XLLUnRegister(Path, 16, bitness);
            }
            catch(Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("FinTools NET Debug:  Error=" + ex.Message);
            }
        }
Posted 16 May, 2019 19:00:12 Top
Andrei Smolin


Add-in Express team


Posts: 16334
Joined: 2006-05-11
Ah, I see. That was my fault. This event occurs when the add-in is being unregistered: this occurs with no Excel running. That is, the add-in module is created outside of the host application. this is why you get ExcelApp not set.

I suggest that you store the information required for unregistration in the registry so that XLLUnRegister could be used with out accessing the Excel application.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 17 May, 2019 04:12:37 Top
fintools




Posts: 8
Joined: 2016-03-24
That was an easy enough workaround. This issue is resolved.

For those that find this thread, and are having problems with accessing Excel's registry settings, while the Add-In is built as Any CPU, if you have a bitness-specific XLL to use, you'll also need to access the specific registry view for the bitness of Excel. Getting a string was easy, but setting it for 64 bit was a little tricky, and needed advapi32.dll.

I had to stumble my way into this, so I welcome any refactoring or suggestions.



        private static readonly uint HKEY_LOCAL_MACHINE = 0x80000002;
        private static readonly uint HKEY_CURRENT_USER = 0x80000001;
        private static readonly uint KEY_WOW64_64KEY = 0x0100;
        private static readonly uint KEY_WOW64_32KEY = 0x0200;
        private static readonly uint KEY_ALL_ACCESS = 0xF003F;


        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern int RegCreateKeyEx(
        uint hKey,
        string lpSubKey,
        int Reserved,
        string lpClass,
        uint dwOptions,
        uint samDesired,
        uint lpSecurityAttributes,
        ref uint phkResult,
        ref uint lpdwDisposition);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern int RegSetValueEx(
        IntPtr hKey,
        [MarshalAs(UnmanagedType.LPStr)] string lpValueName,
        int Reserved,
        Microsoft.Win32.RegistryValueKind dwType,
        [MarshalAs(UnmanagedType.LPStr)] string lpData,
        uint cbData);

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegSetValueEx")]
        private static extern int RegSetValueEx(
            IntPtr keyBase,
            string valueName,
            IntPtr reserved,
            RegistryValueKind type,
            ref int data,
            int rawDataLength);


       public static string GetCurrentUserString32(string subKey, string stringName)
        {
            try
            {
                RegistryKey regKey =
                    RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32)
                        .OpenSubKey(subKey);
                return regKey?.GetValue(stringName).ToString() ?? "";
            }
            catch
            {
                return "";
            }
        }

        public static string GetCurrentUserString64(string subKey, string stringName)
        {
            try
            {
                RegistryKey regKey =
                    RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)
                        .OpenSubKey(subKey);
                return regKey?.GetValue(stringName).ToString() ?? "";
            }
            catch
            {
                return "";
            }
        }

        public static bool SetCurrentUserString32(string subKey, string stringName, string stringValue)
        {
            try
            {
                uint nKey = 0;
                uint nDisposition = 0;

                int ok = RegCreateKeyEx(0x80000001, subKey, 0, String.Empty, 0,
                        KEY_WOW64_32KEY | KEY_ALL_ACCESS, 0, ref nKey, ref nDisposition);

                if (ok == 0)
                {
                    ok = RegSetValueEx(new System.IntPtr(nKey), stringName, 0,
                         RegistryValueKind.String, stringValue, (uint)stringValue.Length);
                }

                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool SetCurrentUserString64(string subKey, string stringName, string stringValue)
        {
            try
            {
                uint nKey = 0;
                uint nDisposition = 0;

                int ok = RegCreateKeyEx(0x80000001, subKey, 0, String.Empty, 0, 
                        KEY_WOW64_64KEY | KEY_ALL_ACCESS, 0, ref nKey, ref nDisposition);

                if (ok == 0)
                {
                   ok = RegSetValueEx(new System.IntPtr(nKey), stringName, 0, 
                        RegistryValueKind.String, stringValue, (uint)stringValue.Length);
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
Posted 17 May, 2019 17:57:04 Top
Andrei Smolin


Add-in Express team


Posts: 16334
Joined: 2006-05-11
Hello Dirk,

Many thanks for sharing your findings!

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 20 May, 2019 04:25:13 Top