コード例 #1
0
        public ConnectionSelector(CrmConnections connections, ConnectionDetail selectedConnection = null, bool allowMultipleSelection = false, bool showPublisButton = false)
        {
            InitializeComponent();

            tsbDeleteConnection.Visible = true;
            tsbUpdateConnection.Visible = true;
            bCancel.Text      = "Cancel";
            bValidate.Visible = true;

            bPublish.Visible = showPublisButton;


            connections.Connections.Sort();
            ConnectionManager.Instance.ConnectionsList = connections;
            ConnectionList             = connections;
            cbAutoPublish.Checked      = connections.PublishAfterUpload;
            cbIgnoreExtensions.Checked = connections.IgnoreExtensions;
            cbExtendedLog.Checked      = connections.ExtendedLog;

            SelectedConnection = selectedConnection;

            lvConnections.MultiSelect = allowMultipleSelection;

            DisplayConnections();
            RefreshComboBoxSelectedConnection();
        }
コード例 #2
0
        /// <summary>
        /// Creates or updates a Crm connection
        /// </summary>
        /// <param name="isCreation">Indicates if it is a connection creation</param>
        /// <param name="connectionToUpdate">Details of the connection to update</param>
        /// <param name="connectionFile">List of connections where the connection is edited from</param>
        /// <returns>Created or updated connection</returns>
        public ConnectionDetail EditConnection(bool isCreation, ConnectionDetail connectionToUpdate, ConnectionFile connectionFile = null)
        {
            var cForm = new ConnectionWizard2(connectionToUpdate)
            {
                StartPosition = FormStartPosition.CenterParent
            };

            if (cForm.ShowDialog(innerAppForm) == DialogResult.OK)
            {
                if (isCreation)
                {
                    if (connectionFile == null)
                    {
                        if (ConnectionManager.Instance.ConnectionsList.Connections.FirstOrDefault(
                                d => d.ConnectionId == cForm.CrmConnectionDetail.ConnectionId) == null)
                        {
                            ConnectionManager.Instance.ConnectionsList.Connections.Add(cForm.CrmConnectionDetail);
                        }
                    }
                    else
                    {
                        var connections = CrmConnections.LoadFromFile(connectionFile.Path);
                        if (connections.Connections.FirstOrDefault(
                                d => d.ConnectionId == cForm.CrmConnectionDetail.ConnectionId) == null)
                        {
                            connections.Connections.Add(cForm.CrmConnectionDetail);
                        }

                        connections.SerializeToFile(connectionFile.Path);
                    }
                }
                else
                {
                    if (connectionFile == null)
                    {
                        ConnectionManager.Instance.ConnectionsList.Connections
                        .Where(x => x.ConnectionId == cForm.CrmConnectionDetail.ConnectionId)
                        .ToList()
                        .ForEach(x => x.UpdateAfterEdit(cForm.CrmConnectionDetail));
                    }
                    else
                    {
                        var connections = CrmConnections.LoadFromFile(connectionFile.Path);
                        foreach (ConnectionDetail detail in connections.Connections)
                        {
                            if (detail.ConnectionId == cForm.CrmConnectionDetail.ConnectionId)
                            {
                                detail.UpdateAfterEdit(cForm.CrmConnectionDetail);
                            }
                        }

                        connections.SerializeToFile(connectionFile.Path);
                    }
                }

                return(cForm.CrmConnectionDetail);
            }

            return(null);
        }
コード例 #3
0
        private void btnOk_Click(object sender, EventArgs e)
        {
            try
            {
                var newCc = CrmConnections.LoadFromFile(txtFilePath.Text);
                OpenedFile = new ConnectionFile(newCc)
                {
                    Path     = txtFilePath.Text,
                    Name     = newCc.Name,
                    LastUsed = DateTime.Now
                };

                if (ConnectionsList.Instance.Files.Any(f => f.Name == OpenedFile.Name))
                {
                    int    cloneId = 1;
                    string newName = OpenedFile.Name ?? "New File";

                    while (ConnectionsList.Instance.Files.FirstOrDefault(f => f.Name == newName) != null)
                    {
                        var rule = new System.Text.RegularExpressions.Regex(".* \\(" + cloneId + "\\)$");
                        if (rule.IsMatch(newName))
                        {
                            cloneId++;
                            newName = $"{OpenedFile?.Name?.Replace($" ({cloneId - 1})", "") ?? "New File"} ({cloneId})";
                        }
                        else
                        {
                            newName = $"{newName} ({cloneId})";
                        }
                    }

                    OpenedFile.Name = newName;

                    MessageBox.Show(this, $"A connection file with this name already exists!\n\nIt has been renamed to '{newName}'", "Warning",
                                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }

                ConnectionManager.ConfigurationFile = txtFilePath.Text;
                ConnectionsList.Instance.Files.First(f => f.Path == txtFilePath.Text).Name = OpenedFile.Name;
                ConnectionManager.Instance.LoadConnectionsList();
                ConnectionsList.Instance.Save();

                OpenedFilePath = txtFilePath.Text;

                DialogResult = DialogResult.OK;
                Close();
            }
            catch (Exception error)
            {
                MessageBox.Show(this, "It seems something went wrong when loading your file: " + error,
                                "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
コード例 #4
0
        /// <summary>
        /// Créé une nouvelle instance de la classe ConnectionSelector
        /// </summary>
        /// <param name="connections">Liste des connexions disponibles</param>
        /// <param name="cManager">Gestionnaire des connexions</param>

        public ConnectionSelector(CrmConnections connections, ConnectionManager cManager, ConnectionDetail selectedConnection = null, bool allowMultipleSelection = false, bool showPublisButton = false)
        {
            InitializeComponent();

            tsbDeleteConnection.Visible = true;
            tsbUpdateConnection.Visible = true;
            bCancel.Text      = "Cancel";
            bValidate.Visible = true;

            bPublish.Visible = showPublisButton;


            connectionManager = cManager;
            connections.Connections.Sort();

            ConnectionList             = connections;
            cbAutoPublish.Checked      = connections.PublishAfterUpload;
            cbIgnoreExtensions.Checked = connections.IgnoreExtensions;
            cbExtendedLog.Checked      = connections.ExtendedLog;

            SelectedConnection = selectedConnection;

            lvConnections.MultiSelect = allowMultipleSelection;

            LoadImages();

            foreach (ConnectionDetail detail in connections.Connections)
            {
                var item = new ListViewItem(detail.ConnectionName);
                item.SubItems.Add(detail.ServerName);
                item.SubItems.Add(detail.OrganizationFriendlyName);
                item.SubItems.Add(detail.OrganizationVersion);
                item.SubItems.Add(detail.SolutionFriendlyName);
                item.Tag        = detail;
                item.Group      = GetGroup(detail.AuthType);
                item.ImageIndex = GetImageIndex(detail);

                lvConnections.Items.Add(item);
            }

            RefreshComboBoxSelectedConnection();

            var groups = new ListViewGroup[lvConnections.Groups.Count];

            lvConnections.Groups.CopyTo(groups, 0);

            Array.Sort(groups, new GroupComparer());

            lvConnections.BeginUpdate();
            lvConnections.Groups.Clear();
            lvConnections.Groups.AddRange(groups);
            lvConnections.EndUpdate();
        }
コード例 #5
0
ファイル: Settings.cs プロジェクト: gasyleiss/CrmUpdater
        /// <summary>
        /// Reads and parses Crm Connections from settings store
        /// </summary>
        /// <returns>Returns Crm Connetions</returns>
        private CrmConnections GetCrmConnections()
        {
            if (_settingsStore.PropertyExists(CollectionPath, ConnectionsPropertyName) == false)
            {
                return(null);
            }

            var connectionsXml = _settingsStore.GetString(CollectionPath, ConnectionsPropertyName);

            try
            {
                var connections    = XmlSerializerHelper.Deserialize <List <ConnectionDetail> >(connectionsXml);
                var crmConnections = new CrmConnections {
                    Connections = connections
                };
                var publisAfterUpload = true;
                if (_settingsStore.PropertyExists(CollectionPath, AutoPublishPropertyName))
                {
                    publisAfterUpload = _settingsStore.GetBoolean(CollectionPath, AutoPublishPropertyName);
                }
                crmConnections.PublishAfterUpload = publisAfterUpload;

                var ignoreExtensions = false;
                if (_settingsStore.PropertyExists(CollectionPath, IgnoreExtensionsProprtyName))
                {
                    ignoreExtensions = _settingsStore.GetBoolean(CollectionPath, IgnoreExtensionsProprtyName);
                }
                crmConnections.IgnoreExtensions = ignoreExtensions;


                var extendedLog = false;
                if (_settingsStore.PropertyExists(CollectionPath, ExtendedLogProprtyName))
                {
                    extendedLog = _settingsStore.GetBoolean(CollectionPath, ExtendedLogProprtyName);
                }
                crmConnections.ExtendedLog = extendedLog;

                foreach (var connection in crmConnections.Connections)
                {
                    if (!string.IsNullOrEmpty(connection.UserPassword))
                    {
                        connection.UserPassword = DecryptString(connection.UserPassword);
                    }
                }

                return(crmConnections);
            }
            catch (Exception)
            {
                Logger.WriteLine("Failed to parse connection settings");
                return(null);
            }
        }
コード例 #6
0
        /// <summary>
        /// Créé une nouvelle instance de la classe ConnectionSelector
        /// </summary>
        /// <param name="connections">Liste des connexions disponibles</param>
        /// <param name="cManager">Gestionnaire des connexions</param>
        public ConnectionSelector(CrmConnections connections, ConnectionManager cManager, bool allowMultipleSelection = false, bool isConnectionSelection = true)
        {
            InitializeComponent();
            this.isConnectionSelection = isConnectionSelection;
            if (isConnectionSelection)
            {
                Text = "Select a connection";
                tsbDeleteConnection.Visible = false;
                tsbUpdateConnection.Visible = false;
                bCancel.Text      = "Cancel";
                bValidate.Visible = true;
            }
            else
            {
                Text = "Connections list";
                tsbDeleteConnection.Visible = true;
                tsbUpdateConnection.Visible = true;
                bCancel.Text      = "Close";
                bValidate.Visible = false;
            }

            connectionManager = cManager;
            connections.Connections.Sort();

            lvConnections.MultiSelect = allowMultipleSelection;

            LoadImages();

            foreach (ConnectionDetail detail in connections.Connections)
            {
                var item = new ListViewItem(detail.ConnectionName);
                item.SubItems.Add(detail.ServerName);
                item.SubItems.Add(detail.Organization);
                item.SubItems.Add(detail.OrganizationVersion);
                item.Tag        = detail;
                item.Group      = GetGroup(detail.AuthType);
                item.ImageIndex = GetImageIndex(detail);

                lvConnections.Items.Add(item);
            }

            var groups = new ListViewGroup[lvConnections.Groups.Count];

            lvConnections.Groups.CopyTo(groups, 0);

            Array.Sort(groups, new GroupComparer());

            lvConnections.BeginUpdate();
            lvConnections.Groups.Clear();
            lvConnections.Groups.AddRange(groups);
            lvConnections.EndUpdate();
        }
コード例 #7
0
        private void btnOk_Click(object sender, EventArgs e)
        {
            CrmConnections cc = new CrmConnections(txtConnectionName.Text);
            cc.SerializeToFile(txtFilePath.Text);

            ConnectionsList.Instance.Files.Add(new ConnectionFile { Name = txtConnectionName.Text, Path = txtFilePath.Text, LastUsed = DateTime.Now });
            ConnectionsList.Instance.Save();

            CreatedFilePath = txtFilePath.Text;

            this.DialogResult = DialogResult.OK;
            this.Close();
        }
コード例 #8
0
        private void btnOk_Click(object sender, EventArgs e)
        {
            CrmConnections cc = new CrmConnections(txtConnectionName.Text);

            cc.SerializeToFile(txtFilePath.Text);

            ConnectionsList.Instance.Files.Add(new ConnectionFile {
                Name = txtConnectionName.Text, Path = txtFilePath.Text, LastUsed = DateTime.Now
            });
            ConnectionsList.Instance.Save();

            CreatedFilePath = txtFilePath.Text;

            this.DialogResult = DialogResult.OK;
            this.Close();
        }
コード例 #9
0
        /// <summary>
        /// Initializes a new instance of class ConnectionSelector
        /// </summary>
        /// <param name="connections">Available connections list</param>
        public ConnectionSelector(CrmConnections connections)
        {
            connections.Connections.Sort();
            _connectionCollection = new ObservableCollection <ConnectionItem>();

            foreach (var detail in connections.Connections)
            {
                _connectionCollection.Add(new ConnectionItem
                {
                    ConnectionInfo = detail,
                    Name           = detail.ConnectionName,
                    Organization   = detail.OrganizationFriendlyName,
                    Server         = detail.ServerName
                });
            }

            InitializeComponent();
        }
コード例 #10
0
        private void btnOk_Click(object sender, EventArgs e)
        {
            CrmConnections cc   = new CrmConnections(txtConnectionName.Text);
            var            file = new ConnectionFile(cc)
            {
                Path     = txtFilePath.Text,
                Name     = txtConnectionName.Text,
                LastUsed = DateTime.Now
            };

            if (ConnectionsList.Instance.Files.Any(f => f.Name == cc.Name))
            {
                int    cloneId = 1;
                string newName = file.Name;

                while (ConnectionsList.Instance.Files.FirstOrDefault(f => f.Name == newName) != null)
                {
                    var rule = new System.Text.RegularExpressions.Regex(".* \\(" + cloneId + "\\)$");
                    if (rule.IsMatch(newName))
                    {
                        cloneId++;
                        newName = $"{cc.Name.Replace($" ({cloneId - 1})", "")} ({cloneId})";
                    }
                    else
                    {
                        newName = $"{newName} ({cloneId})";
                    }
                }

                file.Name = newName;

                MessageBox.Show(this, $@"A connection file with this name already exists!\n\nIt has been renamed to '{newName}'", "Warning",
                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            cc.SerializeToFile(txtFilePath.Text);
            ConnectionsList.Instance.Save();

            CreatedFilePath = txtFilePath.Text;

            DialogResult = DialogResult.OK;
            Close();
        }
コード例 #11
0
ファイル: Settings.cs プロジェクト: gasyleiss/CrmUpdater
        /// <summary>
        /// Writes Crm Connection to settings store
        /// </summary>
        /// <param name="crmConnections">Crm Connections to write to settings store</param>
        private void SetCrmConnections(CrmConnections crmConnections)
        {
            if (crmConnections?.Connections == null)
            {
                _settingsStore.DeletePropertyIfExists(CollectionPath, ConnectionsPropertyName);
                return;
            }
            Dictionary <Guid, string> passwordCache = new Dictionary <Guid, string>();

            foreach (var connection in crmConnections.Connections)
            {
                if (connection.ConnectionId != null && !passwordCache.ContainsKey(connection.ConnectionId.Value))
                {
                    passwordCache.Add(connection.ConnectionId.Value, connection.UserPassword);
                }

                if (!string.IsNullOrEmpty(connection.UserPassword) && connection.SavePassword)
                {
                    connection.UserPassword = EncryptString(connection.UserPassword);
                }
                else
                {
                    connection.UserPassword = null;
                }
            }

            var connectionsXml = XmlSerializerHelper.Serialize(crmConnections.Connections);

            _settingsStore.SetString(CollectionPath, ConnectionsPropertyName, connectionsXml);
            _settingsStore.SetBoolean(CollectionPath, AutoPublishPropertyName, crmConnections.PublishAfterUpload);
            _settingsStore.SetBoolean(CollectionPath, IgnoreExtensionsProprtyName, crmConnections.IgnoreExtensions);
            _settingsStore.SetBoolean(CollectionPath, ExtendedLogProprtyName, crmConnections.ExtendedLog);

            foreach (var connection in crmConnections.Connections)
            {
                if (connection.ConnectionId != null && passwordCache.ContainsKey(connection.ConnectionId.Value))
                {
                    connection.UserPassword = passwordCache[connection.ConnectionId.Value];
                }
            }
        }
コード例 #12
0
        static void Main(string[] args)
        {
            var username = "******";
            var password = ""; // not needed for online connections

            var clientId            = "51f81489-12ee-4a9e-aaae-a2591f45987d";
            var replyUri            = new Uri("app://58145B91-0C36-4500-8554-080854F2AC97");
            var discoveryServiceUrl = new Uri("https://globaldisco.crm.dynamics.com/api/discovery/v2.0/Instances");

            var connectionFileName  = username;
            var connectionDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"MscrmTools\XrmToolBox\Connections");
            var connectionFilePath  = Path.Combine(connectionDirectory, connectionFileName + ".xml");

            var credentials = new ClientCredentials();

            credentials.UserName.UserName = username;
            credentials.UserName.Password = password;

            /* There seems to be some sort of bug in LinqPad where it gets MethodMissing for
             * DiscoverGlobalOrganizations even though it can find it intellisense, and the
             * same code works in a console app. Bizarrely reflection does work. When moved
             * into a real VS solution, the commented out connection code is the way to go (or
             * when the LP bug is fixed)
             *
             *
             * var organizations = CrmServiceClient.DiscoverGlobalOrganizations(discoveryServiceUri: discoveryServiceUrl,
             *                                                               clientCredentials: credentials,
             *                                                               user: null,
             *                                                               clientId: appId,
             *                                                               redirectUri: appReplyUri,
             *                                                               // if you change the prompt behaviour to auto, you'll want to use a different cache for each credential
             *                                                               // otherwise it will keep reusing the last successful connection
             *                                                               tokenCachePath: "",
             *                                                               isOnPrem: false,
             *                                                               authority: string.Empty,
             *                                                               promptBehavior: Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior.SelectAccount,
             *                                                               useDefaultCreds: false);
             */

            var organizations = (OrganizationDetailCollection)typeof(CrmServiceClient)
                                .GetMethod(nameof(CrmServiceClient.DiscoverGlobalOrganizations), BindingFlags.Static | BindingFlags.Public)
                                .Invoke(null, new object[] {
                discoveryServiceUrl,
                credentials,
                null,
                clientId,
                replyUri,
                "",
                false,
                string.Empty,
                Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior.SelectAccount,
                false,
            });

            var connections = organizations.Select(o =>
            {
                var url = new Uri(o.Endpoints[EndpointType.WebApplication]);

                var detail = new ConnectionDetail(createNewId: true)
                {
                    ConnectionId               = o.OrganizationId,
                    UserName                   = username,
                    UserDomain                 = credentials.Windows.ClientCredential.Domain ?? "",
                    AuthType                   = GuessAuthType(credentials, clientId, o),
                    NewAuthType                = GuessNewAuthType(credentials, clientId, o),
                    ConnectionName             = $"{o.FriendlyName}",
                    ServerName                 = url.Host,
                    Organization               = o.UniqueName,
                    OrganizationUrlName        = o.UrlName,
                    OrganizationFriendlyName   = o.FriendlyName,
                    OrganizationVersion        = o.OrganizationVersion,
                    OrganizationServiceUrl     = o.Endpoints[EndpointType.OrganizationService],
                    OrganizationDataServiceUrl = o.Endpoints[EndpointType.OrganizationDataService],
                    WebApplicationUrl          = o.Endpoints[EndpointType.WebApplication],
                    ServerPort                 = url.Port,
                    Timeout       = TimeSpan.FromMinutes(20),
                    EnvironmentId = o.EnvironmentId,
                    OriginalUrl   = url.AbsoluteUri,
                    ReplyUrl      = replyUri.AbsoluteUri,
                };

                if (detail.NewAuthType == AuthenticationType.OAuth && string.IsNullOrEmpty(password))
                {
                    // if we have no password we want it to use the oauth token cache instead
                    // this is signaled by saying we are multifactor
                    detail.UseMfa = true;
                }

                if (Guid.TryParse(clientId, out var azureAppId))
                {
                    detail.AzureAdAppId = azureAppId;
                }

                if (!string.IsNullOrEmpty(password))
                {
                    if (detail.NewAuthType == AuthenticationType.ClientSecret)
                    {
                        detail.SetClientSecret(credentials.UserName.Password);
                    }
                    else
                    {
                        detail.SetPassword(credentials.UserName.Password);
                    }
                }

                switch (DiscoverPurpose(o))
                {
                case OrganizationPurpose.Production:
                    detail.EnvironmentColor     = Color.Red;
                    detail.EnvironmentTextColor = Color.White;
                    detail.EnvironmentText      = $"👎 - {o.FriendlyName}";
                    break;

                case OrganizationPurpose.Test:
                    detail.EnvironmentColor     = Color.Yellow;
                    detail.EnvironmentTextColor = Color.Black;
                    detail.EnvironmentText      = $"✋ - {o.FriendlyName}";
                    break;

                case OrganizationPurpose.Development:
                    detail.EnvironmentColor     = Color.Green;
                    detail.EnvironmentTextColor = Color.White;
                    detail.EnvironmentText      = $"👍 - {o.FriendlyName}";
                    break;
                }

                return(detail);
            });
            var connectionFile = new CrmConnections(connectionFileName);

            connectionFile.Connections.AddRange(connections);
            connectionFile.SerializeToFile(connectionFilePath);

            Console.WriteLine($"Connection file generated successfully: \nPATH: {connectionFilePath}");
            Console.WriteLine("Press any key to exit: ");
            Console.ReadKey();
        }
コード例 #13
0
        /// <summary>
        /// Adds the ToolStripMenuItems representing connections to the
        /// ToolStripDropDownButton
        /// </summary>
        /// <param name="btn">ToolStripDropDownButton where to add connections</param>
        private void AddActionsList(ToolStripDropDownButton btn)
        {
            var list       = new List <ToolStripItem>();
            int filesCount = ConnectionsList.Instance.Files.Count;

            if (filesCount == 0)
            {
                var defaultFilePath = Path.Combine(new FileInfo(ConnectionsList.ConnectionsListFilePath).DirectoryName, "ConnectionsList.Default.xml");

                CrmConnections cc = new CrmConnections("Default");
                cc.SerializeToFile(defaultFilePath);

                ConnectionsList.Instance.Files.Add(new ConnectionFile(cc)
                {
                    Path = defaultFilePath, LastUsed = DateTime.Now
                });
                ConnectionsList.Instance.Save();
            }

            foreach (var file in ConnectionsList.Instance.Files)
            {
                var connections = CrmConnections.LoadFromFile(file.Path);
                connections.Connections.Sort();

                var fileItem = new ToolStripMenuItem(file.Name);
                fileItem.Tag = file;
                if (!mergeConnectionFiles && filesCount > 1)
                {
                    list.Add(fileItem);
                }

                foreach (var cDetail in connections.Connections)
                {
                    ToolStripMenuItem item = new ToolStripMenuItem();
                    item.Text = cDetail.ConnectionName;
                    item.Tag  = cDetail;

                    if (cDetail.UseOnline)
                    {
                        item.Image =
                            RessourceManager.GetImage(
                                "McTools.Xrm.Connection.WinForms.Resources.CRMOnlineLive_16.png");
                    }
                    else if (cDetail.UseOsdp)
                    {
                        item.Image =
                            RessourceManager.GetImage(
                                "McTools.Xrm.Connection.WinForms.Resources.CRMOnlineLive_16.png");
                    }
                    else if (cDetail.UseIfd)
                    {
                        item.Image =
                            RessourceManager.GetImage(
                                "McTools.Xrm.Connection.WinForms.Resources.server_key.png");
                    }
                    else
                    {
                        item.Image =
                            RessourceManager.GetImage(
                                "McTools.Xrm.Connection.WinForms.Resources.server.png");
                    }

                    BuildActionItems(item);
                    if (!mergeConnectionFiles && filesCount > 1)
                    {
                        fileItem.DropDownItems.Add(item);
                    }
                    else
                    {
                        list.Add(item);
                    }
                }

                if (!mergeConnectionFiles && filesCount > 1)
                {
                    if (fileItem.DropDownItems.Count > 0)
                    {
                        fileItem.DropDownItems.Add(new ToolStripSeparator());
                    }
                }

                var newConnectionItem = new ToolStripMenuItem();
                newConnectionItem.Text   = "Create new connection";
                newConnectionItem.Image  = (Image)resources.GetObject("server_add");
                newConnectionItem.Click += newConnectionItem_Click;

                if (!mergeConnectionFiles && filesCount > 1)
                {
                    fileItem.DropDownItems.Add(newConnectionItem);
                }
            }

            if (mergeConnectionFiles || filesCount == 1)
            {
                if (list.Count > 0)
                {
                    list.Add(new ToolStripSeparator());
                }

                var newConnectionItem = new ToolStripMenuItem();
                newConnectionItem.Text   = "Create new connection";
                newConnectionItem.Image  = (Image)resources.GetObject("server_add");
                newConnectionItem.Click += newConnectionItem_Click;

                list.Add(newConnectionItem);
            }

            if (InvokeRequired)
            {
                Invoke(new Action(() =>
                {
                    btn.DropDownItems.Clear();
                    btn.DropDownItems.AddRange(list.ToArray());
                }));
            }
            else
            {
                btn.DropDownItems.Clear();
                btn.DropDownItems.AddRange(list.ToArray());
            }
        }