<Fix>: Prevent component configuration crashes, add a copyable error dialog, increase revision to 3.9.3145.109
Cause: * A configuration control can reject an incompatible configuration and return null. * ComponentsManagerDlg accessed the rejected configuration without validation, causing a NullReferenceException and closing TBF. * The standard MessageBox was difficult to read and did not provide convenient access to technical details. Solution: 1. Added configuration validation * Validates the configuration returned by the component control. * Logs the rejected control and configuration types. * Cancels the add operation without terminating TBF. 2. Added a reusable error details dialog * Displays a clear error summary and structured technical details. * Allows the diagnostic text to be selected and copied. * Added Copy and Close actions and registered the new form in TBF.csproj. 3. Increased revision * Updated revision to 3.9.3145.109.
This commit is contained in:
@@ -3387,6 +3387,12 @@
|
||||
<Compile Include="UI\Shared\ErrorDlg.designer.cs">
|
||||
<DependentUpon>ErrorDlg.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\Shared\ErrorDetailsDlg.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="UI\Shared\ErrorDetailsDlg.Designer.cs">
|
||||
<DependentUpon>ErrorDetailsDlg.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\Shared\IParentOfListViewEx.cs" />
|
||||
<Compile Include="UI\Shared\ITabWithListViewEx.cs" />
|
||||
<Compile Include="UI\Shared\LoginDlgWithBenchSelection.cs">
|
||||
@@ -4391,6 +4397,10 @@
|
||||
<EmbeddedResource Include="UI\Shared\ClosingTbfForm.resx">
|
||||
<DependentUpon>ClosingTbfForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="UI\Shared\ErrorDetailsDlg.resx">
|
||||
<DependentUpon>ErrorDetailsDlg.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="UI\Shared\ErrorDlg.resx">
|
||||
<DependentUpon>ErrorDlg.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
@@ -424,10 +424,35 @@ namespace TBF.UI.Bench.Components
|
||||
/// Create a single component of the selected type
|
||||
///
|
||||
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
|
||||
cfgControl.Config = cfg;
|
||||
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
|
||||
cfgControl.Config = cfg;
|
||||
|
||||
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
|
||||
if (cfgControl.Config == null)
|
||||
{
|
||||
string controlType = cfgControl.GetType().FullName;
|
||||
string configType = cfg.GetType().FullName;
|
||||
|
||||
string details = string.Join(Environment.NewLine, new[]
|
||||
{
|
||||
"CONFIGURATION CONTROL",
|
||||
controlType,
|
||||
"",
|
||||
"RECEIVED CONFIGURATION",
|
||||
configType,
|
||||
"",
|
||||
"PROBABLE CAUSE",
|
||||
"The configuration control expects a different configuration type.",
|
||||
"Check the type cast in the Config property setter of the configuration control."
|
||||
});
|
||||
|
||||
log.Error(details);
|
||||
ErrorDetailsDlg.ShowError(this, "Invalid component configuration", "The component could not be added.", details);
|
||||
return;
|
||||
}
|
||||
|
||||
int lastItemNr = (cmpntEntities.Count > 0) ? cmpntEntities[cmpntEntities.Count - 1].ItemNr : 0;
|
||||
cfgControl.Config.ItemNr = lastItemNr + 1;
|
||||
|
||||
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
|
||||
cfgForm.CmpntEntities = cmpntEntities;
|
||||
cfgForm.ComponentCfgCtrl = cfgControl;
|
||||
cfgForm.UnlockAfterStart = true;
|
||||
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
namespace TBF.UI.Shared
|
||||
{
|
||||
partial class ErrorDetailsDlg
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
private System.Windows.Forms.TableLayoutPanel mainLayoutPanel;
|
||||
private System.Windows.Forms.TableLayoutPanel headerLayoutPanel;
|
||||
private System.Windows.Forms.PictureBox errorIconPictureBox;
|
||||
private System.Windows.Forms.Label summaryLabel;
|
||||
private System.Windows.Forms.GroupBox technicalDetailsGroupBox;
|
||||
private System.Windows.Forms.TextBox detailsTextBox;
|
||||
private System.Windows.Forms.TableLayoutPanel footerLayoutPanel;
|
||||
private System.Windows.Forms.Label copyStatusLabel;
|
||||
private System.Windows.Forms.FlowLayoutPanel buttonsFlowLayoutPanel;
|
||||
private System.Windows.Forms.Button copyButton;
|
||||
private System.Windows.Forms.Button closeButton;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.mainLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.headerLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.errorIconPictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.summaryLabel = new System.Windows.Forms.Label();
|
||||
this.technicalDetailsGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.detailsTextBox = new System.Windows.Forms.TextBox();
|
||||
this.footerLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.copyStatusLabel = new System.Windows.Forms.Label();
|
||||
this.buttonsFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.closeButton = new System.Windows.Forms.Button();
|
||||
this.copyButton = new System.Windows.Forms.Button();
|
||||
this.mainLayoutPanel.SuspendLayout();
|
||||
this.headerLayoutPanel.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.errorIconPictureBox)).BeginInit();
|
||||
this.technicalDetailsGroupBox.SuspendLayout();
|
||||
this.footerLayoutPanel.SuspendLayout();
|
||||
this.buttonsFlowLayoutPanel.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// mainLayoutPanel
|
||||
//
|
||||
this.mainLayoutPanel.ColumnCount = 1;
|
||||
this.mainLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.mainLayoutPanel.Controls.Add(this.headerLayoutPanel, 0, 0);
|
||||
this.mainLayoutPanel.Controls.Add(this.technicalDetailsGroupBox, 0, 1);
|
||||
this.mainLayoutPanel.Controls.Add(this.footerLayoutPanel, 0, 2);
|
||||
this.mainLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.mainLayoutPanel.Location = new System.Drawing.Point(0, 0);
|
||||
this.mainLayoutPanel.Name = "mainLayoutPanel";
|
||||
this.mainLayoutPanel.Padding = new System.Windows.Forms.Padding(12);
|
||||
this.mainLayoutPanel.RowCount = 3;
|
||||
this.mainLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.AutoSize));
|
||||
this.mainLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.mainLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.AutoSize));
|
||||
this.mainLayoutPanel.Size = new System.Drawing.Size(744, 381);
|
||||
this.mainLayoutPanel.TabIndex = 0;
|
||||
//
|
||||
// headerLayoutPanel
|
||||
//
|
||||
this.headerLayoutPanel.AutoSize = true;
|
||||
this.headerLayoutPanel.ColumnCount = 2;
|
||||
this.headerLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.AutoSize));
|
||||
this.headerLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.headerLayoutPanel.Controls.Add(this.errorIconPictureBox, 0, 0);
|
||||
this.headerLayoutPanel.Controls.Add(this.summaryLabel, 1, 0);
|
||||
this.headerLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.headerLayoutPanel.Location = new System.Drawing.Point(15, 15);
|
||||
this.headerLayoutPanel.Margin = new System.Windows.Forms.Padding(3, 3, 3, 12);
|
||||
this.headerLayoutPanel.Name = "headerLayoutPanel";
|
||||
this.headerLayoutPanel.RowCount = 1;
|
||||
this.headerLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.headerLayoutPanel.Size = new System.Drawing.Size(714, 42);
|
||||
this.headerLayoutPanel.TabIndex = 0;
|
||||
//
|
||||
// errorIconPictureBox
|
||||
//
|
||||
this.errorIconPictureBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.errorIconPictureBox.Margin = new System.Windows.Forms.Padding(3, 3, 12, 3);
|
||||
this.errorIconPictureBox.Name = "errorIconPictureBox";
|
||||
this.errorIconPictureBox.Size = new System.Drawing.Size(32, 32);
|
||||
this.errorIconPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||
this.errorIconPictureBox.TabIndex = 0;
|
||||
this.errorIconPictureBox.TabStop = false;
|
||||
//
|
||||
// summaryLabel
|
||||
//
|
||||
this.summaryLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.summaryLabel.AutoSize = true;
|
||||
this.summaryLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.summaryLabel.Location = new System.Drawing.Point(50, 14);
|
||||
this.summaryLabel.Name = "summaryLabel";
|
||||
this.summaryLabel.Size = new System.Drawing.Size(222, 13);
|
||||
this.summaryLabel.TabIndex = 1;
|
||||
this.summaryLabel.Text = "The requested operation could not be completed.";
|
||||
//
|
||||
// technicalDetailsGroupBox
|
||||
//
|
||||
this.technicalDetailsGroupBox.Controls.Add(this.detailsTextBox);
|
||||
this.technicalDetailsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.technicalDetailsGroupBox.Location = new System.Drawing.Point(15, 72);
|
||||
this.technicalDetailsGroupBox.Name = "technicalDetailsGroupBox";
|
||||
this.technicalDetailsGroupBox.Padding = new System.Windows.Forms.Padding(8);
|
||||
this.technicalDetailsGroupBox.Size = new System.Drawing.Size(714, 249);
|
||||
this.technicalDetailsGroupBox.TabIndex = 1;
|
||||
this.technicalDetailsGroupBox.TabStop = false;
|
||||
this.technicalDetailsGroupBox.Text = "Technical details";
|
||||
//
|
||||
// detailsTextBox
|
||||
//
|
||||
this.detailsTextBox.BackColor = System.Drawing.SystemColors.Window;
|
||||
this.detailsTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.detailsTextBox.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.detailsTextBox.Location = new System.Drawing.Point(8, 21);
|
||||
this.detailsTextBox.Multiline = true;
|
||||
this.detailsTextBox.Name = "detailsTextBox";
|
||||
this.detailsTextBox.ReadOnly = true;
|
||||
this.detailsTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.detailsTextBox.Size = new System.Drawing.Size(698, 220);
|
||||
this.detailsTextBox.TabIndex = 0;
|
||||
this.detailsTextBox.WordWrap = false;
|
||||
//
|
||||
// footerLayoutPanel
|
||||
//
|
||||
this.footerLayoutPanel.AutoSize = true;
|
||||
this.footerLayoutPanel.ColumnCount = 2;
|
||||
this.footerLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.footerLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.AutoSize));
|
||||
this.footerLayoutPanel.Controls.Add(this.copyStatusLabel, 0, 0);
|
||||
this.footerLayoutPanel.Controls.Add(this.buttonsFlowLayoutPanel, 1, 0);
|
||||
this.footerLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.footerLayoutPanel.Location = new System.Drawing.Point(15, 327);
|
||||
this.footerLayoutPanel.Name = "footerLayoutPanel";
|
||||
this.footerLayoutPanel.RowCount = 1;
|
||||
this.footerLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.footerLayoutPanel.Size = new System.Drawing.Size(714, 39);
|
||||
this.footerLayoutPanel.TabIndex = 2;
|
||||
//
|
||||
// copyStatusLabel
|
||||
//
|
||||
this.copyStatusLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.copyStatusLabel.AutoSize = true;
|
||||
this.copyStatusLabel.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
this.copyStatusLabel.Location = new System.Drawing.Point(3, 13);
|
||||
this.copyStatusLabel.Name = "copyStatusLabel";
|
||||
this.copyStatusLabel.Size = new System.Drawing.Size(0, 13);
|
||||
this.copyStatusLabel.TabIndex = 0;
|
||||
//
|
||||
// buttonsFlowLayoutPanel
|
||||
//
|
||||
this.buttonsFlowLayoutPanel.AutoSize = true;
|
||||
this.buttonsFlowLayoutPanel.Controls.Add(this.closeButton);
|
||||
this.buttonsFlowLayoutPanel.Controls.Add(this.copyButton);
|
||||
this.buttonsFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.buttonsFlowLayoutPanel.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
|
||||
this.buttonsFlowLayoutPanel.Location = new System.Drawing.Point(544, 3);
|
||||
this.buttonsFlowLayoutPanel.Name = "buttonsFlowLayoutPanel";
|
||||
this.buttonsFlowLayoutPanel.Size = new System.Drawing.Size(167, 33);
|
||||
this.buttonsFlowLayoutPanel.TabIndex = 1;
|
||||
//
|
||||
// closeButton
|
||||
//
|
||||
this.closeButton.AutoSize = true;
|
||||
this.closeButton.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.closeButton.Location = new System.Drawing.Point(89, 3);
|
||||
this.closeButton.Name = "closeButton";
|
||||
this.closeButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.closeButton.TabIndex = 0;
|
||||
this.closeButton.Text = "Close";
|
||||
this.closeButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// copyButton
|
||||
//
|
||||
this.copyButton.AutoSize = true;
|
||||
this.copyButton.Location = new System.Drawing.Point(8, 3);
|
||||
this.copyButton.Name = "copyButton";
|
||||
this.copyButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.copyButton.TabIndex = 1;
|
||||
this.copyButton.Text = "Copy";
|
||||
this.copyButton.UseVisualStyleBackColor = true;
|
||||
this.copyButton.Click += new System.EventHandler(this.copyButton_Click);
|
||||
//
|
||||
// ErrorDetailsDlg
|
||||
//
|
||||
this.AcceptButton = this.closeButton;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.closeButton;
|
||||
this.ClientSize = new System.Drawing.Size(744, 381);
|
||||
this.Controls.Add(this.mainLayoutPanel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(600, 320);
|
||||
this.Name = "ErrorDetailsDlg";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Error";
|
||||
this.mainLayoutPanel.ResumeLayout(false);
|
||||
this.mainLayoutPanel.PerformLayout();
|
||||
this.headerLayoutPanel.ResumeLayout(false);
|
||||
this.headerLayoutPanel.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.errorIconPictureBox)).EndInit();
|
||||
this.technicalDetailsGroupBox.ResumeLayout(false);
|
||||
this.technicalDetailsGroupBox.PerformLayout();
|
||||
this.footerLayoutPanel.ResumeLayout(false);
|
||||
this.footerLayoutPanel.PerformLayout();
|
||||
this.buttonsFlowLayoutPanel.ResumeLayout(false);
|
||||
this.buttonsFlowLayoutPanel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
|
||||
|
||||
namespace TBF.UI.Shared
|
||||
{
|
||||
public partial class ErrorDetailsDlg : Form
|
||||
{
|
||||
public ErrorDetailsDlg()
|
||||
{
|
||||
InitializeComponent();
|
||||
errorIconPictureBox.Image = SystemIcons.Error.ToBitmap();
|
||||
}
|
||||
|
||||
public ErrorDetailsDlg(string title, string summary, string details) : this()
|
||||
{
|
||||
Text = title;
|
||||
summaryLabel.Text = summary;
|
||||
detailsTextBox.Text = details;
|
||||
}
|
||||
|
||||
public static DialogResult ShowError(IWin32Window owner, string title, string summary, string details)
|
||||
{
|
||||
using (ErrorDetailsDlg dialog = new ErrorDetailsDlg(title, summary, details))
|
||||
{
|
||||
return dialog.ShowDialog(owner);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
detailsTextBox.Select(0, 0);
|
||||
closeButton.Focus();
|
||||
}
|
||||
|
||||
private void copyButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(detailsTextBox.Text);
|
||||
copyButton.Text = "Copied";
|
||||
copyStatusLabel.Text = "Technical details copied to clipboard.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
copyStatusLabel.Text = "Copy failed: " + ex.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Reference in New Issue
Block a user