I still get "unable to create specified ActiveX control" errors on some machines

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

I still get "unable to create specified ActiveX control" errors on some machines
 
Javlon Juraev




Posts: 6
Joined: 2020-10-26
Hi,

I raised this issue before and got the following response from you guys:

"First off, make sure your ADXTaskPane component specifies the correct type name in the ControlProgId property: a typical mistake is to leave this property unchanged after you rename the User Control and/or the project namespace.

Secondly, make sure your code doesn't produce an exception when the task pane instance is being created. A typical way to get such an exception would be to initialize a complex-type variable declared on the class level of the UserControl component. I suggest that you initialize such variables in an event of the UserControl component."

I checked for the first issue and it's not the case. The error happens only on machines of some of my clients - not all.

I am checking for the second cause, but cannot find where the problem is.

The TaskPane instance is being created inside InitializeComponent() in AddinModule.Designer.cs


 private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddinModule));
            
            . . .

            this.savodxonTaskPane = new AddinExpress.MSO.ADXTaskPane(this.components);
    
            . . .

            // 
            // savodxonTaskPane
            // 
            this.savodxonTaskPane.ControlProgID = "savodxon.savodxonControl";
            this.savodxonTaskPane.Title = "Savodxon";
            this.savodxonTaskPane.Visible = false;
            this.savodxonTaskPane.Width = 500;
            // 
            // AddinModule
            // 
            this.AddinName = "savodxon";
            this.DisplayAlerts = false;
            this.SupportedApps = AddinExpress.MSO.ADXOfficeHostApp.ohaWord;
            this.TaskPanes.Add(this.savodxonTaskPane);
            this.OnTaskPaneAfterCreate += new AddinExpress.MSO.ADXTaskPaneAfterCreate_EventHandler(this.AddinModule_OnTaskPaneAfterCreate);

        }


This code is generated by visual studio, when I create task pane in design mode.

And I have AddinModule_OnTaskPaneAfterCreate event handler in AddinModule.cs


private void AddinModule_OnTaskPaneAfterCreate(object sender, ADXTaskPane.ADXCustomTaskPaneInstance instance, object control)
        {
            savodxonControl = instance.Control as savodxonControl;
        }


I need to assign the current instance of userControl to savodxonControl variable, so that I can manipulate the controls in that userControl later.

I still think that the problem is happening while creating and registering an instance of ADXTaskPane - on some machines UAC does not allow the taskPane to be created and registered. That AddinModule_OnTaskPaneAfterCreate event is not being fired - so savodxonControl variable remains to be null.

The error appears at the very startup of MS Word (when I open MS Word and it shows the startup menu). So, this also indicates that the problem is with creating and registering an instance of ADXTaskPane.

I would really appreciate your help.
Posted 22 Aug, 2021 11:08:40 Top
Andrei Smolin


Add-in Express team


Posts: 18018
Joined: 2006-05-11
Hello Javlon,

I suppose there's another way to get this issue. If you have a complex-type variable declared on the class-level of your savodxonControl class, make sure that variable is initialized in an event, not by an initializer. Say, this would apply to a variable holding a logger that logs debug messages.

Regards from Poland (CEST),

Andrei Smolin
Add-in Express Team Leader
Posted 23 Aug, 2021 03:37:10 Top
Javlon Juraev




Posts: 6
Joined: 2020-10-26
Here is the entire code of savodxonControl.cs


using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Word = Microsoft.Office.Interop.Word;
using System.Net;
using System.IO;
using Newtonsoft.Json;

namespace savodxon
{
    public partial class savodxonControl : UserControl
    {
        public savodxonControl()
        {
            InitializeComponent();
            
            ToolTip tt = new ToolTip();
            tt.SetToolTip(skipErrorButton, "Oʻtkazib yuborish");
            tt.SetToolTip(skipErrorAllButton, "Barini oʻtkazib yuborish");
            tt.SetToolTip(addToDictionaryButton, "Shaxsiy lugʻatga qoʻshish");
        }

        private void prevErrorButton_Click(object sender, EventArgs e)
        {
            if (AddinModule.IDs.IndexOf(AddinModule.activeID) > 0)
            {
                goToError(AddinModule.IDs[AddinModule.IDs.IndexOf(AddinModule.activeID) - 1]);
            } else
            {
                goToError(AddinModule.IDs[AddinModule.IDs.Count - 1]);
            }
            
        }

        private void nextErrorButton_Click(object sender, EventArgs e)
        {
            if (AddinModule.IDs.IndexOf(AddinModule.activeID) < AddinModule.IDs.Count - 1)
            {
                goToError(AddinModule.IDs[AddinModule.IDs.IndexOf(AddinModule.activeID) + 1]);
            }
            else
            {
                goToError(AddinModule.IDs[0]);
            }
        }

        public void populateSuggestionBox(string[] suggestions)
        {
            suggestionList.Controls.Clear();
            int newSize = 16;

            if (suggestions.Length > 0)
            {
                foreach (string suggestion in suggestions)
                {
                    Button sb = new Button();
                    sb.Text = suggestion;                    
                    sb.Font = new Font(sb.Font.FontFamily, newSize);
                    sb.FlatStyle = FlatStyle.Flat;
                    sb.AutoSize = true;
                    sb.Click += new EventHandler(applyCorrection);
                    suggestionList.Controls.Add(sb);
                }
            }
            else
            {
                Button sb = new Button();
                sb.Text = "- topilmadi -";
                sb.Font = new Font(sb.Font.FontFamily, newSize);
                sb.FlatStyle = FlatStyle.Flat;
                sb.AutoSize = true;
                sb.Enabled = false;
                suggestionList.Controls.Add(sb);
            }
        }

        private void applyCorrection(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            string replacement = btn.Text;
            Word.ContentControl cc = AddinModule.CurrentInstance.WordApp.ActiveDocument.SelectContentControlsByTitle(AddinModule.activeID)[1];
            Word.Range rng = cc.Range;
            rng.Text = replacement;
            rng.Font.Shading.BackgroundPatternColor = Word.WdColor.wdColorAutomatic;

            int deletedIndex = AddinModule.IDs.IndexOf(AddinModule.activeID);
            int remaining = removeAc(AddinModule.activeID);

            cc.Delete(false);
            Word.Range endRng = AddinModule.CurrentInstance.WordApp.ActiveDocument.Range(rng.End, rng.End);
            endRng.Select();

            if (remaining > 0)
            {
                if (deletedIndex < AddinModule.IDs.Count)
                {
                    goToError(AddinModule.IDs[deletedIndex]);
                }
                else
                {
                    goToError(AddinModule.IDs[0]);
                }
            }
            else
            {
                AddinModule.CurrentInstance.savodxonTaskPane.Visible = false;
            }
        }

        private void skipError(object sender, EventArgs e)
        {
            Word.ContentControl cc = AddinModule.CurrentInstance.WordApp.ActiveDocument.SelectContentControlsByTitle(AddinModule.activeID)[1];
            Word.Range rng = cc.Range;
            rng.Font.Shading.BackgroundPatternColor = Word.WdColor.wdColorAutomatic;

            int deletedIndex = AddinModule.IDs.IndexOf(AddinModule.activeID);
            int remaining = removeAc(AddinModule.activeID);

            cc.Delete(false);
            Word.Range endRng = AddinModule.CurrentInstance.WordApp.ActiveDocument.Range(rng.End, rng.End);
            endRng.Select();

            if (remaining > 0)
            {
                if (deletedIndex < AddinModule.IDs.Count)
                {
                    goToError(AddinModule.IDs[deletedIndex]);
                }
                else
                {
                    goToError(AddinModule.IDs[0]);
                }
            }
            else
            {
                AddinModule.CurrentInstance.savodxonTaskPane.Visible = false;
            }
        }

        private void skipErrorAll(object sender, EventArgs e)
        {
            List<string> deletedIDs = new List<string>(); ;
            Word.ContentControl ac = AddinModule.CurrentInstance.WordApp.ActiveDocument.SelectContentControlsByTitle(AddinModule.activeID)[1];

            string text = ac.Tag;

            int remaining = AddinModule.IDs.Count;
            int deletedIndex = AddinModule.IDs.IndexOf(AddinModule.activeID);

            foreach (string id in AddinModule.IDs)
            {
                Word.ContentControls tempCCs = AddinModule.CurrentInstance.WordApp.ActiveDocument.SelectContentControlsByTitle(id);
                if (tempCCs != null && tempCCs.Count > 0)
                {
                    if (tempCCs[1].Range.Text == text)
                    {
                        tempCCs[1].Range.Font.Shading.BackgroundPatternColor = Word.WdColor.wdColorAutomatic;
                        tempCCs[1].Delete(false);
                        deletedIDs.Add(id);
                    }
                }
            }

            foreach (string id in deletedIDs)
            {
                remaining = removeAc(id);
            }

            if (remaining > 0)
            {
                if (deletedIndex < AddinModule.IDs.Count)
                {
                    goToError(AddinModule.IDs[deletedIndex]);
                }
                else
                {
                    goToError(AddinModule.IDs[0]);
                }
            }
            else
            {
                AddinModule.CurrentInstance.savodxonTaskPane.Visible = false;
            }
        }

        public void goToError(string id)
        {
            Cursor.Current = Cursors.WaitCursor;
            AddinModule.CurrentInstance.savodxonTaskPane.Visible = true;
            
            AddinModule.activeID = id;

            if (AddinModule.IDs.Count > 0)
            {
                Word.ContentControl ac = AddinModule.CurrentInstance.WordApp.ActiveDocument.SelectContentControlsByTitle(id)[1];

                Word.Range rng = ac.Range;
                string alphabet = savodxonSettings.Default.script;

                string text = ac.Tag;

                if (alphabet == "cyr")
                {
                    text = AddinModule.toLatin(text);
                }

                try
                {
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                    //ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

                    string token = savodxonSettings.Default.token;
                    WebRequest request = WebRequest.Create(AddinModule.theHost + "api/office_suggestions");
                    request.Method = "POST";
                    string postData = "text=" + text + "&token=" + token;
                    byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                    request.ContentType = "application/x-www-form-urlencoded";
                    request.ContentLength = byteArray.Length;
                    Stream dataStream = request.GetRequestStream();
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    dataStream.Close();
                    WebResponse resuult = request.GetResponse();
                    //System.Diagnostics.Debug.WriteLine(((HttpWebResponse)resuult));
                    if (((HttpWebResponse)resuult).StatusDescription == "OK")
                    {
                        dataStream = resuult.GetResponseStream();
                        StreamReader reader = new StreamReader(dataStream);
                        string responseFromServer = reader.ReadToEnd();
                        //System.Diagnostics.Debug.WriteLine(responseFromServer);
                        reader.Close();
                        dataStream.Close();
                        resuult.Close();

                        AddinModule.Response response = JsonConvert.DeserializeObject<AddinModule.Response>(responseFromServer);
                        if (response.success)
                        {
                            if (response.isSuggested)
                            {
                                string[] suggestions = response.suggestions;
                                if (alphabet == "cyr")
                                {
                                    string[] suggestionsCyr = new string[suggestions.Length];
                                    for (int i = 0; i < suggestions.Length; i++)
                                    {
                                        suggestionsCyr[i] = AddinModule.toCyrill(suggestions[i]);
                                    }
                                    suggestions = suggestionsCyr;
                                }

                                populateSuggestionBox(suggestions);

                                Word.Range endRng = AddinModule.CurrentInstance.WordApp.ActiveDocument.Range(rng.End, rng.End);
                                endRng.Select();

                                Cursor.Current = Cursors.Default;
                                return;
                            }
                            else
                            {
                                string[] noSuggestions = { };
                                populateSuggestionBox(noSuggestions);

                                rng.Select();

                                Cursor.Current = Cursors.Default;
                                return;
                            }
                        }
                        else
                        {
                            string messageBoxText = response.message;
                            string caption = "Xato";
                            MessageBoxButtons button = MessageBoxButtons.OK;
                            MessageBoxIcon icon = MessageBoxIcon.Warning;
                            MessageBox.Show(messageBoxText, caption, button, icon);

                            Cursor.Current = Cursors.Default;
                            return;
                        }
                    }
                    else
                    {
                        string messageBoxText = "Savodxon saytiga ulanishda texnik xato yuz berdi. Qurilmangiz internet tarmogʻiga ulanganligiga ishonch hosil qiling.";
                        string caption = "Xato";
                        MessageBoxButtons button = MessageBoxButtons.OK;
                        MessageBoxIcon icon = MessageBoxIcon.Warning;
                        MessageBox.Show(messageBoxText, caption, button, icon);

                        Cursor.Current = Cursors.Default;
                        return;
                    }
                }
                catch (Exception ex)
                {
                    string messageBoxText = ex.Message;
                    string caption = "Xato";
                    MessageBoxButtons button = MessageBoxButtons.OK;
                    MessageBoxIcon icon = MessageBoxIcon.Warning;
                    MessageBox.Show(messageBoxText, caption, button, icon);
                    return;
                }
            }
        } 

        public static int removeAc(string id)
        {
            AddinModule.IDs.Remove(id);
            return AddinModule.IDs.Count;
        }

        public static void saveUserDictionary(System.Collections.Specialized.StringCollection ud)
        {
            bool isNet = AddinModule.isInternetConnected();

            if (!isNet)
            {
                return;
            }

            string token = savodxonSettings.Default.token;
            string[] dictionary = new string[ud.Count];
            ud.CopyTo(dictionary, 0);
            string json = JsonConvert.SerializeObject(dictionary);
            try
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                WebRequest request = WebRequest.Create(AddinModule.theHost + "api/office_save_user_dictionary");
                request.Method = "POST";

                string postData = "token=" + token + "&dictionary=" + json;
                byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = byteArray.Length;
                Stream dataStream = request.GetRequestStream();
                dataStream.Write(byteArray, 0, byteArray.Length);
                dataStream.Close();
                WebResponse resuult = request.GetResponse();
                if (((HttpWebResponse)resuult).StatusDescription == "OK")
                {
                    dataStream = resuult.GetResponseStream();
                    StreamReader reader = new StreamReader(dataStream);
                    string responseFromServer = reader.ReadToEnd();
                    //System.Diagnostics.Debug.WriteLine(responseFromServer);
                    reader.Close();
                    dataStream.Close();
                    resuult.Close();

                    AddinModule.Response response = JsonConvert.DeserializeObject<AddinModule.Response>(responseFromServer);
                    if (response.success)
                    {
                        savodxonSettings.Default.userDictionary = ud;
                        savodxonSettings.Default.Save();
                    }
                    else
                    {
                        string messageBoxText = "Shaxsiy lugʻatingizni saqlashda xatolik yuz berdi.";
                        string caption = "Xato";
                        MessageBoxButtons button = MessageBoxButtons.OK;
                        MessageBoxIcon icon = MessageBoxIcon.Warning;
                        MessageBox.Show(messageBoxText, caption, button, icon);
                        return;
                    }
                }
                else
                {
                    string messageBoxText = "Savodxon saytiga ulanishda texnik xato yuz berdi. Qurilmangiz internet tarmogʻiga ulanganligiga ishonch hosil qiling.";
                    string caption = "Xato";
                    MessageBoxButtons button = MessageBoxButtons.OK;
                    MessageBoxIcon icon = MessageBoxIcon.Warning;
                    MessageBox.Show(messageBoxText, caption, button, icon);
                    return;
                }
            }
            catch (Exception ex)
            {
                string messageBoxText = ex.Message;
                string caption = "Xato";
                MessageBoxButtons button = MessageBoxButtons.OK;
                MessageBoxIcon icon = MessageBoxIcon.Warning;
                MessageBox.Show(messageBoxText, caption, button, icon);
                return;
            }
        }

        private void addToDictionary(object sender, EventArgs e)
        {
            List<string> deletedIDs = new List<string>(); ;
            Word.ContentControl ac = AddinModule.CurrentInstance.WordApp.ActiveDocument.SelectContentControlsByTitle(AddinModule.activeID)[1];

            string text = ac.Tag;

            System.Collections.Specialized.StringCollection userDictionary = savodxonSettings.Default.userDictionary;
             userDictionary.Add(text);

            saveUserDictionary(userDictionary);

            int remaining = AddinModule.IDs.Count;
            int deletedIndex = AddinModule.IDs.IndexOf(AddinModule.activeID);

            foreach (string id in AddinModule.IDs)
            {
                Word.ContentControls tempCCs = AddinModule.CurrentInstance.WordApp.ActiveDocument.SelectContentControlsByTitle(id);
                if (tempCCs != null && tempCCs.Count > 0)
                {
                    if (tempCCs[1].Range.Text == text)
                    {
                        tempCCs[1].Range.Font.Shading.BackgroundPatternColor = Word.WdColor.wdColorAutomatic;
                        tempCCs[1].Delete(false);
                        deletedIDs.Add(id);
                    }
                }
            }

            foreach (string id in deletedIDs)
            {
                remaining = removeAc(id);
            }

            if (remaining > 0)
            {
                if (deletedIndex < AddinModule.IDs.Count)
                {
                    goToError(AddinModule.IDs[deletedIndex]);
                }
                else
                {
                    goToError(AddinModule.IDs[0]);
                }
            }
            else
            {
                AddinModule.CurrentInstance.savodxonTaskPane.Visible = false;
            }
        }
    }
}



Only methods are declared at class-level - no variables. Or am I missing something from your answer?
Posted 23 Aug, 2021 06:23:45 Top
Andrei Smolin


Add-in Express team


Posts: 18018
Joined: 2006-05-11
ToolTip tt = new ToolTip()


This line can cause an issue. When the Garbage Collector runs, it will remove the tt variable because there are no references to it. I don't know whether the original issue relates to this issue. Anyway, you'd need to fix it, too. To do this, declare a Tooltip-type variabke on the class level and use it in your code, not the tt variable.

Regards from Poland (CEST),

Andrei Smolin
Add-in Express Team Leader
Posted 23 Aug, 2021 07:27:47 Top