From d98b4bdf5c4a45b4bebb5a4fa38bf914e97946be Mon Sep 17 00:00:00 2001 From: MscrmTools Date: Tue, 31 Oct 2023 10:13:14 +0100 Subject: [PATCH] Removal of Plugins Store --- XrmToolBox.sln | 16 +- XrmToolBox/AppCode/AppInsights/AppInsights.cs | 340 ++++++++++++++++++ .../AppCode/AppInsights/InstallationInfo.cs | 79 ++++ XrmToolBox/New/NewForm.cs | 154 +++----- XrmToolBox/New/PluginForm.Designer.cs | 3 +- XrmToolBox/New/PluginsForm.cs | 5 +- 6 files changed, 481 insertions(+), 116 deletions(-) create mode 100644 XrmToolBox/AppCode/AppInsights/AppInsights.cs create mode 100644 XrmToolBox/AppCode/AppInsights/InstallationInfo.cs diff --git a/XrmToolBox.sln b/XrmToolBox.sln index 3fbfa1ba..4e6a9f9c 100644 --- a/XrmToolBox.sln +++ b/XrmToolBox.sln @@ -13,8 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XrmToolBox.Extensibility", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XrmToolBox.AutoUpdater", "XrmToolBox.AutoUpdater\XrmToolBox.AutoUpdater.csproj", "{564C72C8-586E-4218-B6B3-F464F7C3903A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XrmToolBox.PluginsStore", "XrmToolBox.PluginsStore\XrmToolBox.PluginsStore.csproj", "{EBCB3D22-03F2-40D2-B949-05CAE575F2EA}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LicenseChecker", "LicenseChecker", "{08305693-A5D7-41FA-B476-20874647809B}" ProjectSection(SolutionItems) = preProject LicenseChecker\McTools.StopAdvertisement.dll = LicenseChecker\McTools.StopAdvertisement.dll @@ -73,18 +71,6 @@ Global {564C72C8-586E-4218-B6B3-F464F7C3903A}.Release|Mixed Platforms.Build.0 = Release|Any CPU {564C72C8-586E-4218-B6B3-F464F7C3903A}.Release|x86.ActiveCfg = Release|Any CPU {564C72C8-586E-4218-B6B3-F464F7C3903A}.Release|x86.Build.0 = Release|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Debug|x86.ActiveCfg = Debug|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Debug|x86.Build.0 = Debug|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Release|Any CPU.Build.0 = Release|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Release|x86.ActiveCfg = Release|Any CPU - {EBCB3D22-03F2-40D2-B949-05CAE575F2EA}.Release|x86.Build.0 = Release|Any CPU {626AEBA8-4315-4D82-B8B9-B94200FD7589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {626AEBA8-4315-4D82-B8B9-B94200FD7589}.Debug|Any CPU.Build.0 = Debug|Any CPU {626AEBA8-4315-4D82-B8B9-B94200FD7589}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -105,8 +91,8 @@ Global {5BF1E228-F898-40CF-B8FB-8412D8C81CFF} = {1A7814D2-1185-484E-92CC-7DD71DDE6488} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - BuildVersion_ConfigurationName = Release SolutionGuid = {5CC3AFE2-F092-40F3-A540-539389A045B6} + BuildVersion_ConfigurationName = Release EndGlobalSection GlobalSection(CodealikeProperties) = postSolution SolutionGuid = 2bf66b53-ea6f-433b-b455-00e70ee33cd0 diff --git a/XrmToolBox/AppCode/AppInsights/AppInsights.cs b/XrmToolBox/AppCode/AppInsights/AppInsights.cs new file mode 100644 index 00000000..16550ae8 --- /dev/null +++ b/XrmToolBox/AppCode/AppInsights/AppInsights.cs @@ -0,0 +1,340 @@ +/* *********************************************************** + * XTBAppInsights.cs + * Found at: https://gist.github.com/rappen/fbdbb644b3fffec1305b00a51b007fa6 + * Created by: Jonas Rapp https://jonasr.app/ + * Immensely inspired by: code from Jason Lattimer https://github.com/jlattimer/D365AppInsights + * + * Simplifies logging to Azure Application Insights from XrmToolBox tools. + * + * Sample from tool constructor: + * ai = new AppInsights("https://dc.services.visualstudio.com/v2/track", "[a guid that is the key to your appinsights resource]", Assembly.GetExecutingAssembly(), "[my custom tool name]"); + * Sample call: + * ai.WriteEvent(action, count, duration, HandleAIResult); + * Sample HandleAIResult: + * private void HandleAIResult(string result) + * { + * if (!string.IsNullOrEmpty(result)) { LogError("Failed to write to Application Insights:\n{0}", result); } + * } + * + * Enjoy responsibly. + * **********************************************************/ + +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Reflection; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.Text; +using XrmToolBox.AppCode.AppInsights; + +public static class Extensions +{ + public static string PaddedVersion(this Version version, int majorpad, int minorpad, int buildpad, int revisionpad) + { + return string.Format($"{{0:D{majorpad}}}.{{1:D{minorpad}}}.{{2:D{buildpad}}}.{{3:D{revisionpad}}}", version.Major, version.Minor, version.Build, version.Revision); + } +} + +public class AiConfig +{ + /// + /// Initializes Application Insights configuration. + /// When called from a tool, make sure to pass Assembly.GetExecutingAssembly() as loggingassembly parameter!! + /// + /// AppInsights endpoint, usually https://dc.services.visualstudio.com/v2/track + /// Instrumentation Key for the AppInsights instance in the Azure portal + /// Assembly info to include in logging, usually pass Assembly.GetExecutingAssembly() + /// Override name of the tool, defaults to last part of the logging assembly name + public AiConfig(string endpoint, string ikey, Assembly loggingassembly = null, string toolname = null) + { + AiEndpoint = endpoint; + InstrumentationKey = ikey; + LoggingAssembly = loggingassembly ?? Assembly.GetExecutingAssembly(); + PluginName = toolname ?? GetLastDotPart(LoggingAssembly.GetName().Name); + PluginVersion = LoggingAssembly.GetName().Version.PaddedVersion(1, 4, 2, 2); + InstallationId = InstallationInfo.Instance.InstallationId; + // This will disable logging if the calling assembly is compiled with debug configuration + LogEvents = !LoggingAssembly.GetCustomAttributes().Any(d => d.IsJITTrackingEnabled); + + var isc = new XrmToolBox.Extensibility.ItSecurityChecker(); + LogEvents = LogEvents && !isc.IsStatisticsCollectDisabled(); + } + + public string AiEndpoint { get; } + public Guid InstallationId { get; set; } + public string InstrumentationKey { get; } + public bool LogEvents { get; set; } = true; + public Assembly LoggingAssembly { get; } + public string OperationName { get; set; } + public string PluginName { get; set; } + public string PluginVersion { get; set; } + public Guid SessionId { get; } = Guid.NewGuid(); + public string XTBVersion { get; set; } = GetLastDotPart(Assembly.GetEntryAssembly().GetName().Name) + " " + Assembly.GetEntryAssembly().GetName().Version.PaddedVersion(1, 4, 2, 2); + + private static string GetLastDotPart(string identifier) + { + return identifier == null ? null : !identifier.Contains(".") ? identifier : identifier.Substring(identifier.LastIndexOf('.') + 1); + } +} + +public class AppInsights +{ + private readonly AiConfig _aiConfig; + private int seq = 1; + + /// + /// Initializes Application Insights instance. + /// When called from a tool, make sure to pass Assembly.GetExecutingAssembly() as loggingassembly parameter!! + /// + /// AppInsights endpoint, usually https://dc.services.visualstudio.com/v2/track + /// Instrumentation Key for the AppInsights instance in the Azure portal + /// Assembly info to include in logging, usually pass Assembly.GetExecutingAssembly() + /// Override name of the tool, defaults to last part of the logging assembly name + public AppInsights(string endpoint, string ikey, Assembly loggingassembly, string toolname = null) + { + _aiConfig = new AiConfig(endpoint, ikey, loggingassembly, toolname); + } + + /// + /// Obsolete constructor + /// + /// Application Insights configuration + [Obsolete("Use constructor accepting parameters endpoint, ikey, loggingassembly and toolname instead.", false)] + public AppInsights(AiConfig aiConfig) + { + _aiConfig = aiConfig; + } + + public void WriteEvent(string eventName, double? count = null, double? duration = null, Action resultHandler = null) + { + if (!_aiConfig.LogEvents) return; + var logRequest = GetLogRequest("Event"); + logRequest.Data.BaseData.Name = eventName; + if (count != null || duration != null) + { + logRequest.Data.BaseData.Measurements = new AiMeasurements + { + Count = count ?? 0, + Duration = duration ?? 0 + }; + } + var json = SerializeRequest(logRequest); + SendToAi(json, resultHandler); + } + + public void WritePageView(string pluginName, string pluginVersion, double? count = null, double? duration = null, Action resultHandler = null) + { + if (!_aiConfig.LogEvents) return; + var logRequest = GetLogRequest("PageView"); + logRequest.Data.BaseData.Name = pluginName; + logRequest.Data.BaseData.Properties = new AiProperties + { + PluginVersion = pluginVersion + }; + + if (count != null || duration != null) + { + logRequest.Data.BaseData.Measurements = new AiMeasurements + { + Count = count ?? 0, + Duration = duration ?? 0 + }; + } + var json = SerializeRequest(logRequest); + SendToAi(json, resultHandler); + } + + public void WritePluginEvent(string pluginName, string pluginVersion, string eventName, double? count = null, double? duration = null, Action resultHandler = null) + { + if (!_aiConfig.LogEvents) return; + var logRequest = GetLogRequest("Event"); + logRequest.Data.BaseData.Name = eventName; + logRequest.Data.BaseData.Properties = new AiProperties + { + PluginName = pluginName, + PluginVersion = pluginVersion + }; + if (count != null || duration != null) + { + logRequest.Data.BaseData.Measurements = new AiMeasurements + { + Count = count ?? 0, + Duration = duration ?? 0 + }; + } + var json = SerializeRequest(logRequest); + SendToAi(json, resultHandler); + } + + private static string SerializeRequest(object o) + { + using (MemoryStream stream = new MemoryStream()) + { + DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); + serializer.WriteObject(stream, o); + stream.Position = 0; + StreamReader reader = new StreamReader(stream); + string json = reader.ReadToEnd(); + + return json; + } + } + + private AiLogRequest GetLogRequest(string action) + { + return new AiLogRequest(seq++, _aiConfig, action); + } + + private async void SendToAi(string json, Action handleresult = null) + { + var result = string.Empty; +#if DEBUG +#else + try + { + using (HttpClient client = HttpHelper.GetHttpClient()) + { + var content = new StringContent(json, Encoding.UTF8, "application/x-json-stream"); + var response = await client.PostAsync(_aiConfig.AiEndpoint, content); + + if (!response.IsSuccessStatusCode) + { + result = response.ToString(); + } + } + } + catch (Exception e) + { + result = e.ToString(); + } +#endif + handleresult?.Invoke(result); + } +} + +public class HttpHelper +{ + public static HttpClient GetHttpClient() + { + HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Add("Connection", "close"); + + return client; + } +} + +#region DataContracts + +[DataContract] +public class AiBaseData +{ + [DataMember(Name = "measurements")] + public AiMeasurements Measurements { get; set; } + + [DataMember(Name = "name")] + public string Name { get; set; } + + [DataMember(Name = "properties")] + public AiProperties Properties { get; set; } +} + +[DataContract] +public class AiData +{ + [DataMember(Name = "baseData")] + public AiBaseData BaseData { get; set; } + + [DataMember(Name = "baseType")] + public string BaseType { get; set; } +} + +[DataContract] +public class AiLogRequest +{ + public AiLogRequest(int sequence, AiConfig aiConfig, string action) + { + Name = $"Microsoft.ApplicationInsights.{aiConfig.InstrumentationKey}.{action}"; + Time = $"{DateTime.UtcNow:O}"; + Sequence = sequence.ToString("0000000000"); + InstrumentationKey = aiConfig.InstrumentationKey; + Tags = new AiTags + { + OSVersion = aiConfig.XTBVersion, + DeviceType = aiConfig.PluginName, + ApplicationVersion = aiConfig.PluginVersion, + UserId = aiConfig.InstallationId.ToString(), + SessionId = aiConfig.SessionId.ToString(), + OperationName = aiConfig.OperationName + }; + Data = new AiData + { + BaseType = $"{action}Data", + BaseData = new AiBaseData() + }; + } + + [DataMember(Name = "data")] + public AiData Data { get; set; } + + [DataMember(Name = "iKey")] + public string InstrumentationKey { get; set; } + + [DataMember(Name = "name")] + public string Name { get; set; } + + [DataMember(Name = "seq")] + public string Sequence { get; set; } + + [DataMember(Name = "tags")] + public AiTags Tags { get; set; } + + [DataMember(Name = "time")] + public string Time { get; set; } +} + +[DataContract] +public class AiMeasurements +{ + [DataMember(Name = "count")] + public double Count { get; set; } + + [DataMember(Name = "duration")] + public double Duration { get; set; } +} + +[DataContract] +public class AiProperties +{ + [DataMember(Name = "pluginName")] + public string PluginName { get; set; } + + [DataMember(Name = "pluginVersion")] + public string PluginVersion { get; set; } +} + +[DataContract] +public class AiTags +{ + [DataMember(Name = "ai.application.ver")] + public string ApplicationVersion { get; set; } + + [DataMember(Name = "ai.device.type")] + public string DeviceType { get; set; } + + [DataMember(Name = "ai.operation.name")] + public string OperationName { get; set; } + + [DataMember(Name = "ai.device.osVersion")] + public string OSVersion { get; set; } + + [DataMember(Name = "ai.session.id")] + public string SessionId { get; set; } = Guid.NewGuid().ToString(); + + [DataMember(Name = "ai.user.id")] + public string UserId { get; set; } +} + +#endregion DataContracts \ No newline at end of file diff --git a/XrmToolBox/AppCode/AppInsights/InstallationInfo.cs b/XrmToolBox/AppCode/AppInsights/InstallationInfo.cs new file mode 100644 index 00000000..5b920dee --- /dev/null +++ b/XrmToolBox/AppCode/AppInsights/InstallationInfo.cs @@ -0,0 +1,79 @@ +using System; +using System.IO; +using System.Xml; +using XrmToolBox.Extensibility; +using XrmToolBox.ToolLibrary.AppCode; + +namespace XrmToolBox.AppCode.AppInsights +{ + public class InstallationInfo + { + private const string OptionFileName = "XrmToolBox.Installation.xml"; + + private static InstallationInfo instance; + + private InstallationInfo() + { + } + + public static InstallationInfo Instance + { + get + { + if (instance == null) + { + instance = Load(); + } + + if (instance?.InstallationId == Guid.Empty) + { + instance?.Save(); + } + + return instance; + } + } + + public DateTime InstallationDate { get; set; } = DateTime.Now; + public Guid InstallationId { get; set; } + + public void Save() + { + if (InstallationId == Guid.Empty) + { + InstallationId = Guid.NewGuid(); + } + if (!Directory.Exists(Paths.SettingsPath)) + { + Directory.CreateDirectory(Paths.SettingsPath); + } + + var settingsFile = Path.Combine(Paths.SettingsPath, OptionFileName); + + XmlSerializerHelper.SerializeToFile(this, settingsFile); + } + + private static InstallationInfo Load() + { + if (!Directory.Exists(Paths.SettingsPath)) + { + Directory.CreateDirectory(Paths.SettingsPath); + } + + var settingsFile = Path.Combine(Paths.SettingsPath, OptionFileName); + + if (File.Exists(settingsFile)) + { + try + { + var document = new XmlDocument(); + document.Load(settingsFile); + + return (InstallationInfo)XmlSerializerHelper.Deserialize(document.OuterXml, typeof(InstallationInfo)); + } + catch { } + } + return new InstallationInfo(); + } + } +} \ No newline at end of file diff --git a/XrmToolBox/New/NewForm.cs b/XrmToolBox/New/NewForm.cs index 3e4cbe29..de789344 100644 --- a/XrmToolBox/New/NewForm.cs +++ b/XrmToolBox/New/NewForm.cs @@ -26,7 +26,6 @@ using XrmToolBox.Extensibility.Interfaces; using XrmToolBox.Forms; using XrmToolBox.New.EventArgs; -using XrmToolBox.PluginsStore; using XrmToolBox.ToolLibrary.Forms; namespace XrmToolBox.New @@ -324,21 +323,15 @@ private async Task LoadStore() { try { - if (Options.Instance.UseLegacyToolLibrary) + ItSecurityChecker isc = new ItSecurityChecker(); + isc.LoadRepositories(); + store = new ToolLibrary.ToolLibrary(Options.Instance, isc.Repositories); + store.AllowConnectionControlPreRelease = Options.Instance.ConnectionControlsAllowPreReleaseUpdates; + ((PluginsForm2)pluginsForm).Store = (ToolLibrary.ToolLibrary)store; + + if (!((ToolLibrary.ToolLibrary)store).HasConnectivityToXrmToolBoxPortal) { - if (store == null) - { - store = new StoreFromPortal(Options.Instance.ConnectionControlsAllowPreReleaseUpdates); - await ((StoreFromPortal)store).LoadNuget(); - } - } - else - { - ItSecurityChecker isc = new ItSecurityChecker(); - isc.LoadRepositories(); - store = new ToolLibrary.ToolLibrary(Options.Instance, isc.Repositories); - store.AllowConnectionControlPreRelease = Options.Instance.ConnectionControlsAllowPreReleaseUpdates; - ((PluginsForm2)pluginsForm).Store = (ToolLibrary.ToolLibrary)store; + throw new Exception("Unable to connect to load tools. Please check your network settings"); } return true; @@ -1804,107 +1797,73 @@ private void OpenPluginsStore(bool showUpdateOnly = false) pnlPluginsUpdate.Visible = false; - if (Options.Instance.UseLegacyToolLibrary) + if (libraryForm == null || libraryForm.IsDisposed) { - // If the options were not initialized, it means we are using the - // new plugins store for the first time. Copy values from main - // options file - if (!PluginsStore.Options.Instance.IsInitialized) + if (!(store is ToolLibrary.ToolLibrary)) { - PluginsStore.Options.Instance.DisplayPluginsStoreOnStartup = Options.Instance.DisplayPluginsStoreOnStartup; - PluginsStore.Options.Instance.PluginsStoreShowInstalled = Options.Instance.PluginsStoreShowInstalled; - PluginsStore.Options.Instance.PluginsStoreShowIncompatible = Options.Instance.PluginsStoreShowIncompatible; - PluginsStore.Options.Instance.PluginsStoreShowNew = Options.Instance.PluginsStoreShowNew; - PluginsStore.Options.Instance.PluginsStoreShowUpdates = Options.Instance.PluginsStoreShowUpdates; - PluginsStore.Options.Instance.UseLegacy = false; - PluginsStore.Options.Instance.IsInitialized = true; + ItSecurityChecker isc = new ItSecurityChecker(); + isc.LoadRepositories(); + store = new ToolLibrary.ToolLibrary(Options.Instance, isc.Repositories); + store.LoadTools().GetAwaiter().GetResult(); } - using (var form = new StoreFormFromPortal(Options.Instance.ConnectionControlsAllowPreReleaseUpdates)) + if (store.PluginsCount == 0 || store.Categories == null) { - form.PluginsClosingRequested += (s, evt) => - { - RequestCloseTabs(dpMain.Contents.OfType(), new PluginCloseInfo(ToolBoxCloseReason.CloseAll)); - }; - - // Avoid scanning for new files during Plugins Store usage. - pluginsForm.PluginManager.IsWatchingForNewPlugins = false; - form.ShowDialog(this); - pluginsForm.PluginManager.IsWatchingForNewPlugins = true; - pluginsForm.ReloadPluginsList(); - PrepareCategories(); + MessageBox.Show(this, "Tool Library is not yet initialzed, please wait few seconds", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; } - // Apply option to show Plugins Store on startup on main options - if (Options.Instance.DisplayPluginsStoreOnStartup != PluginsStore.Options.Instance.DisplayPluginsStoreOnStartup) + + libraryForm = new ToolLibraryForm((ToolLibrary.ToolLibrary)store, Options.Instance); + libraryForm.PluginsClosingRequested += (s, evt) => { - Options.Instance.DisplayPluginsStoreOnStartup = PluginsStore.Options.Instance.DisplayPluginsStoreOnStartup ?? false; - } - } - else - { - if (libraryForm == null || libraryForm.IsDisposed) + RequestCloseTabs(dpMain.Contents.OfType(), new PluginCloseInfo(ToolBoxCloseReason.CloseAll)); + }; + libraryForm.PluginsOpeningRequested += (s, evt) => { - if (!(store is ToolLibrary.ToolLibrary)) + var plm = PluginManagerExtended.Instance.Manifest.PluginMetadata.FirstOrDefault(pm => evt.Plugin.Files.Any(f => Path.GetFileName(f).Equals(Path.GetFileName(pm.AssemblyFilename), StringComparison.InvariantCultureIgnoreCase))); + if (plm == null) { - ItSecurityChecker isc = new ItSecurityChecker(); - isc.LoadRepositories(); - store = new ToolLibrary.ToolLibrary(Options.Instance, isc.Repositories); - store.LoadTools().GetAwaiter().GetResult(); + MessageBox.Show(this, "Unable to find the tool metadata!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; } - - if (store.PluginsCount == 0 || store.Categories == null) + var plugin = PluginManagerExtended.Instance.ValidatedPluginsExt.FirstOrDefault(p => p.Metadata.Name == plm.Name); + if (plugin == null) { - MessageBox.Show(this, "Tool Library is not yet initialzed, please wait few seconds", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + MessageBox.Show(this, "Unable to find the tool metadata!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - libraryForm = new ToolLibraryForm((ToolLibrary.ToolLibrary)store, Options.Instance); - libraryForm.PluginsClosingRequested += (s, evt) => - { - RequestCloseTabs(dpMain.Contents.OfType(), new PluginCloseInfo(ToolBoxCloseReason.CloseAll)); - }; - libraryForm.PluginsOpeningRequested += (s, evt) => - { - var plm = PluginManagerExtended.Instance.Manifest.PluginMetadata.FirstOrDefault(pm => evt.Plugin.Files.Any(f => Path.GetFileName(f).Equals(Path.GetFileName(pm.AssemblyFilename), StringComparison.InvariantCultureIgnoreCase))); - if (plm == null) - { - MessageBox.Show(this, "Unable to find the tool metadata!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - var plugin = PluginManagerExtended.Instance.ValidatedPluginsExt.FirstOrDefault(p => p.Metadata.Name == plm.Name); - if (plugin == null) - { - MessageBox.Show(this, "Unable to find the tool metadata!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - if (service == null) - { - ConnectUponApproval(plugin); - } - else - { - DisplayPluginControl(plugin); - } - }; - ((ToolLibrary.ToolLibrary)store).OnToolsMetadataRefreshRequested += (s, evt) => - { - PluginManagerExtended.Instance.Recompose(); - }; - ((ToolLibrary.ToolLibrary)store).PluginsUpdated += (s, evt) => + if (service == null) { - pluginsForm.ReloadPluginsList(); - PrepareCategories(); - }; - - if (showUpdateOnly) + ConnectUponApproval(plugin); + } + else { - libraryForm.ShowUpdatesOnly(); + DisplayPluginControl(plugin); } - } + }; + ((ToolLibrary.ToolLibrary)store).OnToolsMetadataRefreshRequested += (s, evt) => + { + PluginManagerExtended.Instance.Recompose(); + }; + ((ToolLibrary.ToolLibrary)store).PluginsUpdated += (s, evt) => + { + pluginsForm.ReloadPluginsList(); + PrepareCategories(); + }; - libraryForm.Show(dpMain, DockState.Document); + if (showUpdateOnly) + { + libraryForm.ShowUpdatesOnly(); + } } + + libraryForm.Show(dpMain, DockState.Document); + } + + private void SettingsForm_OnProxySettingsChanged(object sender, System.EventArgs e) + { + llRetryInitToolLibrary_LinkClicked(this, new LinkLabelLinkClickedEventArgs(llRetryInitToolLibrary.Links[0])); } private void tsbImpersonate_Click(object sender, System.EventArgs e) @@ -1970,6 +1929,7 @@ private async void tsddbTools_DropDownItemClicked(object sender, ToolStripItemCl if (settingsForm == null || settingsForm.IsDisposed) { settingsForm = new SettingsForm(); + settingsForm.OnProxySettingsChanged += SettingsForm_OnProxySettingsChanged; } settingsForm.Show(dpMain, DockState.Document); diff --git a/XrmToolBox/New/PluginForm.Designer.cs b/XrmToolBox/New/PluginForm.Designer.cs index da115858..0b7d698a 100644 --- a/XrmToolBox/New/PluginForm.Designer.cs +++ b/XrmToolBox/New/PluginForm.Designer.cs @@ -73,7 +73,7 @@ private void InitializeComponent() // toolStripStatusLabel // this.toolStripStatusLabel.Name = "toolStripStatusLabel"; - this.toolStripStatusLabel.Size = new System.Drawing.Size(761, 27); + this.toolStripStatusLabel.Size = new System.Drawing.Size(915, 27); this.toolStripStatusLabel.Spring = true; this.toolStripStatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // @@ -268,6 +268,7 @@ private void InitializeComponent() this.pnlMain.ResumeLayout(false); this.tlpHighlight.ResumeLayout(false); this.pnlHighlight.ResumeLayout(false); + this.pnlHighlight.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbEnvLogo)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); diff --git a/XrmToolBox/New/PluginsForm.cs b/XrmToolBox/New/PluginsForm.cs index 6e111f47..731e7dd0 100644 --- a/XrmToolBox/New/PluginsForm.cs +++ b/XrmToolBox/New/PluginsForm.cs @@ -15,7 +15,6 @@ using XrmToolBox.Extensibility.Interfaces; using XrmToolBox.Extensibility.UserControls; using XrmToolBox.New.EventArgs; -using XrmToolBox.PluginsStore; namespace XrmToolBox.New { @@ -29,7 +28,7 @@ public partial class PluginsForm : DockContent, IToolsForm private string filterText; private Thread searchThread; private PluginModel selectedPluginModel; - private StoreFromPortal store; + private ToolLibrary.ToolLibrary store; #endregion Variables @@ -551,7 +550,7 @@ private void DisplayPlugins(object filter = null) { if (store == null) { - store = new StoreFromPortal(Options.Instance.ConnectionControlsAllowPreReleaseUpdates); + store = new ToolLibrary.ToolLibrary(Options.Instance, new Dictionary()); } if (store.XrmToolBoxPlugins == null)