Просмотр исходного кода

1、增加额定高度、卷筒直径、编码器分辨率三个参数,并自动计算步长
2、控制参数配置中数字部分的验证

LC 1 неделя назад
Родитель
Сommit
6dcf57a8b6

+ 7 - 5
App.config

@@ -17,8 +17,6 @@
     <DbProviderFactories>
       <remove invariant="System.Data.SQLite.EF6" />
       <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
-      <remove invariant="System.Data.SQLite" />
-      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
     </DbProviderFactories>
   </system.data>
   <runtime>
@@ -29,7 +27,7 @@
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-9.0.0.8" newVersion="9.0.0.8" />
+        <bindingRedirect oldVersion="0.0.0.0-10.0.0.8" newVersion="10.0.0.8" />
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
@@ -53,7 +51,7 @@
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
@@ -101,7 +99,11 @@
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="ScottPlot" publicKeyToken="86698dc10387c39e" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-5.0.55.0" newVersion="5.0.55.0" />
+        <bindingRedirect oldVersion="0.0.0.0-5.1.59.0" newVersion="5.1.59.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="SkiaSharp" publicKeyToken="0738eb9f132ed756" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.119.0.0" newVersion="3.119.0.0" />
       </dependentAssembly>
     </assemblyBinding>
   </runtime>

+ 12 - 1
Config/Config.json

@@ -31,7 +31,9 @@
       "WireMaterialType": 1,
       "WireSurfaceType": 1,
       "LiftHightRatio": 2,
-      "TimeDomainSpeed": 1.2,
+      "RatedHeight": 20,
+      "HoistDrumDiameter": 750,
+      "EncoderResolution": 1000,
       "LayType": 1,
       "DisableAlarm": false,
       "InUseSensor": [ 1, 2, 3 ],
@@ -73,6 +75,9 @@
       "WireMaterialType": 1,
       "WireSurfaceType": 1,
       "LiftHightRatio": 2,
+      "RatedHeight": 20,
+      "HoistDrumDiameter": 750,
+      "EncoderResolution": 1000,
       "LayType": 1,
       "DisableAlarm": false,
       "InUseSensor": [ 1, 2, 3, 4 ],
@@ -114,6 +119,9 @@
       "WireMaterialType": 1,
       "WireSurfaceType": 1,
       "LiftHightRatio": 2,
+      "RatedHeight": 20,
+      "HoistDrumDiameter": 750,
+      "EncoderResolution": 1000,
       "LayType": 1,
       "DisableAlarm": false,
       "InUseSensor": [ 1, 2, 3, 4 ],
@@ -155,6 +163,9 @@
       "WireMaterialType": 1,
       "WireSurfaceType": 1,
       "LiftHightRatio": 2,
+      "RatedHeight": 20,
+      "HoistDrumDiameter": 750,
+      "EncoderResolution": 1000,
       "LayType": 1,
       "DisableAlarm": false,
       "InUseSensor": [ 1, 2, 3, 4 ],

+ 1 - 45
Enums/RiskLevel.cs

@@ -1,7 +1,4 @@
-using SWRIS.Models;
-using System;
-using System.ComponentModel;
-using System.Linq;
+using System.ComponentModel;
 
 namespace SWRIS.Enums
 {
@@ -50,45 +47,4 @@ namespace SWRIS.Enums
         ExceededLimit = 5
 
     }
-
-    public static class RiskLevelEvaluator
-    {
-        public static RiskLevel Evaluate(double maxDamageValue, double avgDamageValue)
-        {
-            if (maxDamageValue <= 0 && avgDamageValue <= 0)
-            {
-                return RiskLevel.Normal;
-            }
-            // Check from highest to lowest severity
-            foreach (RiskLevel level in Enum.GetValues(typeof(RiskLevel)).Cast<RiskLevel>().OrderByDescending(x => x))
-            {
-                var attribute = GetRiskLevelConfig(level);
-
-                // First check max damage range
-                bool isMaxRangeMatch = maxDamageValue > attribute.MaxDamageRange.Min && maxDamageValue <= attribute.MaxDamageRange.Max;
-                if (isMaxRangeMatch)
-                {
-                    return level;
-                }
-
-                // If max range doesn't match, then check avg damage range
-                bool isAvgRangeMatch = avgDamageValue > attribute.AvgDamageRange.Min && avgDamageValue <= attribute.AvgDamageRange.Max;
-                if (isAvgRangeMatch)
-                {
-                    return level;
-                }
-            }
-            return RiskLevel.Normal;
-        }
-        public static RiskLevelConfig GetRiskLevelConfig(this RiskLevel level)
-        {
-            return App.Config.RiskLevelSettings.Levels
-                  .FirstOrDefault(x => x.Level == level) ?? new RiskLevelConfig
-                  {
-                      Level = RiskLevel.Normal,
-                      MaxDamageRange = new Range { Min = 0, Max = 0 },
-                      AvgDamageRange = new Range { Min = 0, Max = 0 },
-                  };
-        }
-    }
 }

+ 7 - 0
Mapping.cs

@@ -24,7 +24,10 @@ namespace SWRIS
             equipmentModel.SerialNo = equipmentSettingViewModel.SerialNo;
             equipmentModel.Supplier = equipmentSettingViewModel.Supplier;
             equipmentModel.LayType = (LayType)equipmentSettingViewModel.LayType;
+            equipmentModel.HoistDrumDiameter = equipmentSettingViewModel.HoistDrumDiameter;
+            equipmentModel.EncoderResolution = equipmentSettingViewModel.EncoderResolution;
             equipmentModel.LiftHightRatio = equipmentSettingViewModel.LiftHightRatio;
+            equipmentModel.RatedHeight = equipmentSettingViewModel.RatedHeight;
             equipmentModel.SoundRiskLevel = equipmentSettingViewModel.SoundRiskLevel;
             equipmentModel.WireMaterialType = (WireMaterialType)equipmentSettingViewModel.WireMaterialType;
             equipmentModel.WireSurfaceType = (WireSurfaceType)equipmentSettingViewModel.WireSurfaceType;
@@ -105,6 +108,9 @@ namespace SWRIS
             equipmentSettingViewModel.RunningStatus = runningStatus;
             equipmentSettingViewModel.LayType = (int)equipmentModel.LayType;
             equipmentSettingViewModel.LiftHightRatio = equipmentModel.LiftHightRatio;
+            equipmentSettingViewModel.HoistDrumDiameter = equipmentModel.HoistDrumDiameter;
+            equipmentSettingViewModel.EncoderResolution = equipmentModel.EncoderResolution;
+            equipmentSettingViewModel.RatedHeight = equipmentModel.RatedHeight;
             equipmentSettingViewModel.SoundRiskLevel = equipmentModel.SoundRiskLevel;
             equipmentSettingViewModel.WireMaterialType = (int)equipmentModel.WireMaterialType;
             equipmentSettingViewModel.WireSurfaceType = (int)equipmentModel.WireSurfaceType;
@@ -170,6 +176,7 @@ namespace SWRIS
             equipmentDataModel.LiftHightRatio = equipmentModel.LiftHightRatio;
             equipmentDataModel.DisableAlarm = equipmentModel.DisableAlarm;
             equipmentDataModel.InUseSensor = equipmentModel.InUseSensor;
+
             // 如果有Parameter数据,设置相关属性
             if (equipmentModel.Parameter != null)
             {

+ 55 - 18
Models/ConfigModel.cs

@@ -10,25 +10,78 @@ namespace SWRIS.Models
 {
     public class ConfigModel
     {
+        /// <summary>
+        /// 系统名称
+        /// </summary>
         public string AppName { get; set; }
+        /// <summary>
+        /// 软件版本号
+        /// </summary>
         public string Version { get; set; }
+        /// <summary>
+        /// 版权/技术支持
+        /// </summary>
         public string Copyright { get; set; }
+        /// <summary>
+        /// Tcp Server 服务Ip地址
+        /// </summary>
         public string IpAddress { get; set; }
+        /// <summary>
+        /// Tcp Server 端口号
+        /// </summary>
         public int Port { get; set; }
+        /// <summary>
+        /// 数据保存天数
+        /// </summary>
         public int DataSaveDays { get; set; } = 120;
+        /// <summary>
+        /// 数据清理时间点
+        /// </summary>
         public TimeSpan CleanScheduledTime { get; set; }
+        /// <summary>
+        /// 损伤附近点数(检测报告内用)
+        /// </summary>
         public int DamageNearPointCount { get; set; } = 20;
+        /// <summary>
+        /// 是否显示调试信息
+        /// </summary>
         public bool ShowDebugMessage { get; set; } = false;
+        /// <summary>
+        /// 语音报警级别
+        /// </summary>
         public RiskLevel SoundRiskLevel { get; set; } = RiskLevel.Moderate;
+        /// <summary>
+        /// 速度波动阈值
+        /// </summary>
         public double SpeedVariationThreshold { get; set; } = 0.25;
+        /// <summary>
+        /// 起重机名称
+        /// </summary>
         public string Crane { get; set; }
+        /// <summary>
+        /// 小车集合
+        /// </summary>
         public List<TrolleyData> Trolleys { get; set; }
+        /// <summary>
+        /// 设备集合
+        /// </summary>
         public List<EquipmentModel> Equipments { get; set; }
+        /// <summary>
+        /// 应用切换
+        /// </summary>
         public List<SwitchInstance> SwitchInstances { get; set; }
+        /// <summary>
+        /// 位置标定
+        /// </summary>
         public CalibrationSettings Calibration { get; set; }
-        public RiskLevelSettings RiskLevelSettings { get; set; }
+        /// <summary>
+        /// 损伤容差范围
+        /// </summary>
         public double DamageExtent { get; set; }
-        public int AlarmValidCount { get; set; }
+        /// <summary>
+        /// 损伤确认频次
+        /// </summary>
+        public int AlarmValidCount { get; set; } = 1;
 
         public string GenerateNewSerialNo()
         {
@@ -69,22 +122,6 @@ namespace SWRIS.Models
         public StopBits StopBits { get; set; }
         public byte Station { get; set; } = 1;
     }
-
-    public class RiskLevelSettings
-    {
-        public List<RiskLevelConfig> Levels { get; set; }
-    }
-    public class RiskLevelConfig
-    {
-        public RiskLevel Level { get; set; }
-        public Range MaxDamageRange { get; set; }
-        public Range AvgDamageRange { get; set; }
-    }
-    public class Range
-    {
-        public int Min { get; set; }
-        public int Max { get; set; }
-    }
     public class TrolleyData
     {
         public int Id { get; set; }

+ 1 - 0
Models/DataCenterModel.cs

@@ -27,6 +27,7 @@ namespace SWRIS.Models
                         SamplingStep = equipment.Parameter.SamplingStep,
                         RopeLength = equipment.Parameter.WireRopeLength,
                         LiftHightRatio = equipment.LiftHightRatio,
+                        LiftHeight = equipment.RatedHeight,
                         DisableAlarm = equipment.DisableAlarm,
                         InUseSensor = equipment.InUseSensor,
                         VariationThreshold = App.Config.SpeedVariationThreshold

+ 14 - 1
Models/EquipmentModel.cs

@@ -32,7 +32,19 @@ namespace SWRIS.Models
         /// <summary>
         /// 绳长/高度倍率
         /// </summary>
-        public double LiftHightRatio { get; set; } = 1;
+        public double LiftHightRatio { get; set; } = 2;
+        /// <summary>
+        /// 卷筒/米轮直径 mm
+        /// </summary>
+        public double HoistDrumDiameter { get; set; } = 750;
+        /// <summary>
+        /// 额定高度(起升高度)m
+        /// </summary>
+        public double RatedHeight { get; set; } = 20;
+        /// <summary>
+        /// 编码器分辨率 PPR
+        /// </summary>
+        public double EncoderResolution { get; set; } = 1000;
         /// <summary>
         /// 报警级别
         /// </summary>
@@ -65,5 +77,6 @@ namespace SWRIS.Models
         /// 参数
         /// </summary>
         public ParameterModel Parameter { get; set; }
+
     }
 }

+ 118 - 3
Models/ViewModel/EquipmentSettingViewModel.cs

@@ -26,6 +26,10 @@ namespace SWRIS.Models.ViewModel
         private ParameterData parameter;
         private bool isConnected;
         private RunningStatus runningStatus = RunningStatus.SpatialNormal;
+        private double hoistDrumDiameter = 750;
+        private double encoderResolution = 1000;
+        private double ratedHeight;
+
         /// <summary>
         /// 绳号
         /// </summary>
@@ -131,6 +135,7 @@ namespace SWRIS.Models.ViewModel
                 OnPropertyChanged(nameof(WireSurfaceType));
             }
         }
+
         /// <summary>
         /// 捻向 1 右交互捻 2 左交互捻 3 右同向捻 4 左同向捻
         /// </summary>
@@ -152,8 +157,11 @@ namespace SWRIS.Models.ViewModel
             get { return liftHightRatio; }
             set
             {
-                liftHightRatio = value;
+                // 倍率最小为 1
+                liftHightRatio = value < 1 ? 1 : value;
                 OnPropertyChanged(nameof(LiftHightRatio));
+                // 倍率变化时按 钢丝绳长度 = 额定高度 × 倍率 重新计算
+                UpdateWireRopeLength();
             }
         }
 
@@ -171,8 +179,19 @@ namespace SWRIS.Models.ViewModel
             get { return parameter; }
             set
             {
+                if (parameter != null)
+                {
+                    parameter.PropertyChanged -= OnParameterPropertyChanged;
+                }
                 parameter = value;
                 OnPropertyChanged(nameof(Parameter));
+                if (parameter != null)
+                {
+                    // 分频系数变化时联动重算采样步长
+                    parameter.PropertyChanged += OnParameterPropertyChanged;
+                }
+                // 参数加载后按当前卷筒直径/编码器分辨率重新计算采样步长
+                UpdateSamplingStep();
             }
         }
         public bool IsConnected
@@ -211,12 +230,90 @@ namespace SWRIS.Models.ViewModel
                 OnPropertyChanged(nameof(RunningStatus));
             }
         }
+        /// <summary>
+        /// 卷筒/米轮直径 mm
+        /// </summary>
+        public double HoistDrumDiameter
+        {
+            get => hoistDrumDiameter; set
+            {
+                hoistDrumDiameter = value;
+                OnPropertyChanged(nameof(HoistDrumDiameter));
+                // 卷筒直径变化时重新计算采样步长
+                UpdateSamplingStep();
+            }
+        }
+        /// <summary>
+        /// 编码器分辨率
+        /// </summary>
+        public double EncoderResolution
+        {
+            get => encoderResolution; set
+            {
+                encoderResolution = value;
+                OnPropertyChanged(nameof(EncoderResolution));
+                // 编码器分辨率变化时重新计算采样步长
+                UpdateSamplingStep();
+            }
+        }
+        /// <summary>
+        /// 额定高度(起升高度)m
+        /// </summary>
+        public double RatedHeight
+        {
+            get { return ratedHeight; }
+            set
+            {
+                ratedHeight = value;
+                OnPropertyChanged(nameof(RatedHeight));
+                // 额定高度变化时按 钢丝绳长度 = 额定高度 × 倍率 重新计算
+                UpdateWireRopeLength();
+            }
+        }
+        /// <summary>
+        /// 根据额定高度与滑轮组倍率计算钢丝绳长度并赋值(钢丝绳长度 = 额定高度 × 倍率),单位 m。
+        /// </summary>
+        private void UpdateWireRopeLength()
+        {
+            if (parameter == null || ratedHeight <= 0 || liftHightRatio <= 0)
+            {
+                return;
+            }
+            parameter.WireRopeLength = (float)(ratedHeight * liftHightRatio);
+        }
+
+        /// <summary>
+        /// 通过卷筒/米轮直径、编码器分辨率与分频系数计算采样步长(mm/点)并同步到设备参数。
+        /// 设备每 分频系数 个编码器脉冲采样一个点,故:
+        /// 采样步长 = 每脉冲位移 × 分频系数 = π × 直径 × 分频系数 / 分辨率
+        /// </summary>
+        private void UpdateSamplingStep()
+        {
+            if (parameter == null || encoderResolution <= 0 || hoistDrumDiameter <= 0 || parameter.FrequencyDivisionFactor <= 0)
+            {
+                return;
+            }
+            parameter.SamplingStep = (float)(Math.PI * hoistDrumDiameter * parameter.FrequencyDivisionFactor / encoderResolution);
+        }
+
+        /// <summary>
+        /// 参数属性变化时联动重算采样步长(分频系数变化场景)
+        /// </summary>
+        private void OnParameterPropertyChanged(object sender, PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName == nameof(ParameterData.FrequencyDivisionFactor))
+            {
+                UpdateSamplingStep();
+            }
+        }
         public List<KeyAndValueDto> RopeCoreTypes => TypeExtension.ToKeyAndDescriptionList(typeof(RopeCoreType));
         public List<KeyAndValueDto> WireMaterialTypes => TypeExtension.ToKeyAndDescriptionList(typeof(WireMaterialType));
         public List<KeyAndValueDto> LayTypes => TypeExtension.ToKeyAndDescriptionList(typeof(LayType));
         public List<KeyAndValueDto> WireSurfaceTypes => TypeExtension.ToKeyAndDescriptionList(typeof(WireSurfaceType));
         public List<KeyAndValueDto> RiskLevels => TypeExtension.ToKeyAndDescriptionList(typeof(RiskLevel));
 
+
+
         public event PropertyChangedEventHandler PropertyChanged;
         protected internal virtual void OnPropertyChanged(string propertyName)
         {
@@ -471,15 +568,32 @@ namespace SWRIS.Models.ViewModel
             }
         }
         /// <summary>
-        /// 钢丝绳长度,单位:m  4字节浮点数
+        /// 钢丝绳长度,单位:m  4字节浮点数(供协议打包/持久化使用)
         /// </summary>
         public float WireRopeLength
         {
             get => wireRopeLength;
             set
             {
-                wireRopeLength = value;
+                // 统一保留 2 位小数,避免浮点运算产生冗长小数位
+                wireRopeLength = (float)Math.Round(value, 2, MidpointRounding.AwayFromZero);
                 OnPropertyChanged(nameof(WireRopeLength));
+                OnPropertyChanged(nameof(WireRopeLengthValue));
+            }
+        }
+        /// <summary>
+        /// 钢丝绳长度(double 显示值,供输入框绑定)。
+        /// float 转 double 会产生二进制噪声(如 41.2f → 41.200000762939453),
+        /// 故暴露 double 值并四舍五入到 2 位小数后再绑定。
+        /// </summary>
+        public double WireRopeLengthValue
+        {
+            get => Math.Round(wireRopeLength, 2);
+            set
+            {
+                wireRopeLength = (float)Math.Round(value, 2, MidpointRounding.AwayFromZero);
+                OnPropertyChanged(nameof(WireRopeLength));
+                OnPropertyChanged(nameof(WireRopeLengthValue));
             }
         }
         /// <summary>
@@ -555,6 +669,7 @@ namespace SWRIS.Models.ViewModel
                 OnPropertyChanged(nameof(TwistFactor));
             }
         }
+
         /// <summary>
         ///  限位1校准位置
         /// </summary>

+ 42 - 15
Pages/ParameterDialog.xaml

@@ -50,7 +50,7 @@
                                 <TextBlock Text="设备" Foreground="#615CDD" FontSize="24" Margin="15" FontWeight="Regular"/>
                                 <Rectangle Height="2" Width="140" Stroke="#3B3B7B"/>
                             </StackPanel>
-                            <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
+                            <StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="0,0,25,0">
                                 <StackPanel Orientation="Horizontal" Margin="0,7" HorizontalAlignment="Right">
                                     <TextBlock Text="版本号" VerticalAlignment="Center"/>
                                     <TextBox Text="{Binding Parameter.MainBoardSoftwareVersion}" IsEnabled="False" Margin="15,0"/>
@@ -63,12 +63,32 @@
                                     <TextBox Margin="15,0" Text="{Binding IpAddress}"/>
                                 </StackPanel>
                                 <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right">
-                                    <TextBlock Text="传感器数量" VerticalAlignment="Center"/>
-                                    <TextBox Margin="15,0" Text="{Binding Parameter.SensorCount}"/>
+                                    <TextBlock Text="卷筒/米轮直径" VerticalAlignment="Center"/>
+                                    <StackPanel Orientation="Horizontal"  Margin="0,0,4,0">
+                                        <pu:NumberInput Margin="15,0,6,0" Width="110" Value="{Binding HoistDrumDiameter}" Minimum="10"/>
+                                        <TextBlock  Text="mm" Width="45" VerticalAlignment="Center"/>
+                                    </StackPanel>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Margin="0,7" HorizontalAlignment="Right" Visibility="Visible">
+                                    <TextBlock Text="编码器分辨率" VerticalAlignment="Center"/>
+                                    <StackPanel Orientation="Horizontal"  Margin="0,0,4,0">
+                                        <pu:NumberInput Margin="15,0,6,0" Width="110" Value="{Binding EncoderResolution}" Minimum="100"/>
+                                        <TextBlock  Text="PPR" Width="45" VerticalAlignment="Center"/>
+                                    </StackPanel>
                                 </StackPanel>
                                 <StackPanel Orientation="Horizontal" Margin="0,7" HorizontalAlignment="Right" Visibility="Visible">
-                                    <TextBlock Text="位/高比例" VerticalAlignment="Center"/>
-                                    <TextBox Margin="15,0" Text="{Binding LiftHightRatio}"/>
+                                    <TextBlock Text="滑轮组倍率" VerticalAlignment="Center"/>
+                                    <StackPanel Orientation="Horizontal"  Margin="0,0,4,0">
+                                        <pu:NumberInput Margin="15,0,6,0" Width="110" Value="{Binding LiftHightRatio}" Minimum="1"/>
+                                        <TextBlock Text="倍" Width="45" VerticalAlignment="Center"/>
+                                    </StackPanel>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Margin="0,7" HorizontalAlignment="Right" Visibility="Visible">
+                                    <TextBlock Text="额定高度" VerticalAlignment="Center"/>
+                                    <StackPanel Orientation="Horizontal"  Margin="0,0,4,0">
+                                        <pu:NumberInput Margin="15,0,6,0" Width="110" Value="{Binding RatedHeight}" Minimum="0"/>
+                                        <TextBlock  Text="m" Width="45" VerticalAlignment="Center"/>
+                                    </StackPanel>
                                 </StackPanel>
                             </StackPanel>
                         </StackPanel>
@@ -130,30 +150,35 @@
                         <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                             <StackPanel Orientation="Horizontal" Margin="0,7" HorizontalAlignment="Right">
                                 <TextBlock Text="钢丝绳绳号" VerticalAlignment="Center"/>
-                                <TextBox Text="{Binding RopeNumber}" Margin="15,0"/>
+                                <pu:NumberInput Value="{Binding RopeNumber}" Margin="15,0" Minimum="1" />
                             </StackPanel>
                             <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right">
                                 <TextBlock Text="钢丝绳名称" VerticalAlignment="Center"/>
                                 <TextBox Margin="15,0" Text="{Binding RopeName}"/>
                             </StackPanel>
+                            <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right">
+                                <TextBlock Text="供应商" VerticalAlignment="Center"/>
+                                <TextBox Margin="15,0" Text="{Binding Supplier}"/>
+                            </StackPanel>
                             <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right">
                                 <TextBlock Text="直径" VerticalAlignment="Center"/>
                                 <StackPanel Orientation="Horizontal"  Margin="0,0,4,0">
-                                    <TextBox Margin="15,0,6,0" Width="110" Text="{Binding Parameter.WireRopeDiameter}"/>
+                                    <pu:NumberInput Margin="15,0,6,0" Width="110" Value="{Binding Parameter.WireRopeDiameter}" Minimum="1"/>
                                     <TextBlock  Text="mm" Width="45" VerticalAlignment="Center"/>
                                 </StackPanel>
                             </StackPanel>
                             <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right">
                                 <TextBlock Text="股丝" VerticalAlignment="Center"/>
-                                <TextBox Margin="15,0,8,0" Width="63" Text="{Binding Parameter.WireRopeStrandCount}"/>
+                                <pu:NumberInput Margin="15,0,8,0" Width="63" Value="{Binding Parameter.WireRopeStrandCount}" Minimum="1"/>
                                 <TextBlock Text="*" VerticalAlignment="Center"/>
-                                <TextBox Margin="7,0,15,0" Width="64" Text="{Binding Parameter.WireRopeStrandWireCount}"/>
+                                <pu:NumberInput Margin="7,0,15,0" Width="64" Value="{Binding Parameter.WireRopeStrandWireCount}" Minimum="1"/>
                             </StackPanel>
                             <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right">
                                 <TextBlock Text="长度" VerticalAlignment="Center"/>
                                 <StackPanel Orientation="Horizontal"  Margin="0,0,4,0">
-                                    <TextBox Margin="15,0,6,0" Width="110" Text="{Binding Parameter.WireRopeLength}"/>
-                                    <TextBlock  Text="m" Width="45" VerticalAlignment="Center"/>
+                                    <pu:NumberInput Margin="15,0,6,0" Width="110" 
+                                                    Value="{Binding Parameter.WireRopeLengthValue}" Minimum="1"/>
+                                    <TextBlock Text="m" Width="45" VerticalAlignment="Center"/>
                                 </StackPanel>
                             </StackPanel>
                             <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right">
@@ -163,10 +188,7 @@
                                     <TextBlock  Text="mm" Width="45" VerticalAlignment="Center"/>
                                 </StackPanel>
                             </StackPanel>
-                            <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right" Visibility="Collapsed">
-                                <TextBlock Text="判伤捻距系数" VerticalAlignment="Center"/>
-                                <TextBox Margin="15,0" Text="{Binding Parameter.TwistFactor}"/>
-                            </StackPanel>
+
                             <StackPanel Orientation="Horizontal" Margin="0,7"  HorizontalAlignment="Right">
                                 <TextBlock Text="钢丝材质" VerticalAlignment="Center"/>
                                 <ComboBox Margin="15,0" Width="150"
@@ -195,6 +217,7 @@
                                   SelectedValue="{Binding WireSurfaceType}" 
                                   DisplayMemberPath="Value" SelectedValuePath="Key" />
                             </StackPanel>
+
                         </StackPanel>
                     </StackPanel>
                     <StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="2" Margin="10,0,10,0">
@@ -246,6 +269,10 @@
                                         <TextBlock Text="报废上限" VerticalAlignment="Center"/>
                                         <TextBox Margin="15,0" Width="120" Text="{Binding Parameter.ScrapUpperLimit}"/>
                                     </StackPanel>
+                                    <StackPanel Orientation="Horizontal" Margin="0,7" HorizontalAlignment="Right">
+                                        <TextBlock Text="判伤捻距系数" VerticalAlignment="Center"/>
+                                        <TextBox Margin="15,0" Width="120" Text="{Binding Parameter.TwistFactor}"/>
+                                    </StackPanel>
                                     <StackPanel Orientation="Horizontal" Margin="0,7" HorizontalAlignment="Right">
                                         <StackPanel Orientation="Vertical" VerticalAlignment="Center">
                                             <TextBlock Text="零点位有效行程" HorizontalAlignment="Right"/>

+ 42 - 50
SWRIS.csproj

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="packages\EntityFramework.6.5.1\build\EntityFramework.props" Condition="Exists('packages\EntityFramework.6.5.1\build\EntityFramework.props')" />
+  <Import Project="packages\EntityFramework.6.5.2\build\EntityFramework.props" Condition="Exists('packages\EntityFramework.6.5.2\build\EntityFramework.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <HotReloadAutoRestart>true</HotReloadAutoRestart>
@@ -69,34 +69,34 @@
     <ApplicationIcon>logo.ico</ApplicationIcon>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="EPPlus, Version=4.5.3.3, Culture=neutral, PublicKeyToken=ea159fdaa78159a1, processorArchitecture=MSIL">
-      <HintPath>packages\EPPlus.4.5.3.3\lib\net40\EPPlus.dll</HintPath>
-    </Reference>
-    <Reference Include="CustomMarshalers" />
     <Reference Include="Dapper, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>packages\Dapper.2.1.66\lib\net461\Dapper.dll</HintPath>
+      <HintPath>packages\Dapper.2.1.79\lib\net461\Dapper.dll</HintPath>
     </Reference>
     <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>packages\EntityFramework.6.5.1\lib\net45\EntityFramework.dll</HintPath>
+      <HintPath>packages\EntityFramework.6.5.2\lib\net45\EntityFramework.dll</HintPath>
     </Reference>
     <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>packages\EntityFramework.6.5.1\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+      <HintPath>packages\EntityFramework.6.5.2\lib\net45\EntityFramework.SqlServer.dll</HintPath>
     </Reference>
+    <Reference Include="EPPlus, Version=4.5.3.3, Culture=neutral, PublicKeyToken=ea159fdaa78159a1, processorArchitecture=MSIL">
+      <HintPath>packages\EPPlus.4.5.3.3\lib\net40\EPPlus.dll</HintPath>
+    </Reference>
+    <Reference Include="CustomMarshalers" />
     <Reference Include="GLWpfControl, Version=3.3.0.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>packages\OpenTK.GLWpfControl.3.3.0\lib\net452\GLWpfControl.dll</HintPath>
     </Reference>
     <Reference Include="HarfBuzzSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>packages\HarfBuzzSharp.7.3.0.3\lib\net462\HarfBuzzSharp.dll</HintPath>
+      <HintPath>packages\HarfBuzzSharp.8.3.1.1\lib\net462\HarfBuzzSharp.dll</HintPath>
     </Reference>
-    <Reference Include="HslCommunication, Version=12.3.3.0, Culture=neutral, PublicKeyToken=3d72ad3b6b5ec0e3, processorArchitecture=MSIL">
-      <HintPath>packages\HslCommunication.12.3.3\lib\net451\HslCommunication.dll</HintPath>
+    <Reference Include="HslCommunication, Version=12.9.2.0, Culture=neutral, PublicKeyToken=3d72ad3b6b5ec0e3, processorArchitecture=MSIL">
+      <HintPath>packages\HslCommunication.12.9.2\lib\net451\HslCommunication.dll</HintPath>
     </Reference>
     <Reference Include="Interop.IWshRuntimeLibrary, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>packages\Interop.IWshRuntimeLibrary.1.0.1\lib\net45\Interop.IWshRuntimeLibrary.dll</HintPath>
       <EmbedInteropTypes>True</EmbedInteropTypes>
     </Reference>
-    <Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.8, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
-      <HintPath>packages\Microsoft.Bcl.AsyncInterfaces.9.0.8\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
+    <Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=10.0.0.8, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>packages\Microsoft.Bcl.AsyncInterfaces.10.0.8\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
     </Reference>
     <Reference Include="Microsoft.Bcl.HashCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
       <HintPath>packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll</HintPath>
@@ -108,7 +108,7 @@
       <HintPath>packages\Microsoft-WindowsAPICodePack-Shell.1.1.5\lib\net48\Microsoft.WindowsAPICodePack.Shell.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+      <HintPath>packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json.Bson, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <HintPath>packages\Newtonsoft.Json.Bson.1.0.3\lib\net45\Newtonsoft.Json.Bson.dll</HintPath>
@@ -122,8 +122,8 @@
     <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>packages\Panuon.WPF.UI.1.3.0.2\lib\net48\Panuon.WPF.UI.dll</HintPath>
     </Reference>
-    <Reference Include="QRCoder, Version=1.6.0.0, Culture=neutral, PublicKeyToken=c4ed5b9ae8358a28, processorArchitecture=MSIL">
-      <HintPath>packages\QRCoder.1.6.0\lib\net40\QRCoder.dll</HintPath>
+    <Reference Include="QRCoder, Version=1.8.0.0, Culture=neutral, PublicKeyToken=c4ed5b9ae8358a28, processorArchitecture=MSIL">
+      <HintPath>packages\QRCoder.1.8.0\lib\net40\QRCoder.dll</HintPath>
     </Reference>
     <Reference Include="QuestPDF, Version=2025.7.1.0, Culture=neutral, PublicKeyToken=0f3c2b2315ff52c8, processorArchitecture=MSIL">
       <HintPath>packages\QuestPDF.2025.7.1\lib\netstandard2.0\QuestPDF.dll</HintPath>
@@ -131,26 +131,26 @@
     <Reference Include="RBush, Version=4.0.0.0, Culture=neutral, PublicKeyToken=c77e27b81f4d0187, processorArchitecture=MSIL">
       <HintPath>packages\RBush.Signed.4.0.0\lib\net47\RBush.dll</HintPath>
     </Reference>
-    <Reference Include="ScottPlot, Version=5.0.55.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL">
-      <HintPath>packages\ScottPlot.5.0.55\lib\net462\ScottPlot.dll</HintPath>
+    <Reference Include="ScottPlot, Version=5.1.59.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL">
+      <HintPath>packages\ScottPlot.5.1.59\lib\net462\ScottPlot.dll</HintPath>
     </Reference>
-    <Reference Include="ScottPlot.WPF, Version=5.0.55.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL">
-      <HintPath>packages\ScottPlot.WPF.5.0.55\lib\net462\ScottPlot.WPF.dll</HintPath>
+    <Reference Include="ScottPlot.WPF, Version=5.1.59.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL">
+      <HintPath>packages\ScottPlot.WPF.5.1.59\lib\net462\ScottPlot.WPF.dll</HintPath>
     </Reference>
     <Reference Include="SixLabors.Fonts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13, processorArchitecture=MSIL">
       <HintPath>packages\SixLabors.Fonts.1.0.0\lib\netstandard2.0\SixLabors.Fonts.dll</HintPath>
     </Reference>
-    <Reference Include="SkiaSharp, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>packages\SkiaSharp.2.88.9\lib\net462\SkiaSharp.dll</HintPath>
+    <Reference Include="SkiaSharp, Version=3.119.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>packages\SkiaSharp.3.119.0\lib\net462\SkiaSharp.dll</HintPath>
     </Reference>
-    <Reference Include="SkiaSharp.HarfBuzz, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>packages\SkiaSharp.HarfBuzz.2.88.9\lib\net462\SkiaSharp.HarfBuzz.dll</HintPath>
+    <Reference Include="SkiaSharp.HarfBuzz, Version=3.119.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>packages\SkiaSharp.HarfBuzz.3.119.0\lib\net462\SkiaSharp.HarfBuzz.dll</HintPath>
     </Reference>
-    <Reference Include="SkiaSharp.Views.Desktop.Common, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>packages\SkiaSharp.Views.Desktop.Common.2.88.9\lib\net462\SkiaSharp.Views.Desktop.Common.dll</HintPath>
+    <Reference Include="SkiaSharp.Views.Desktop.Common, Version=3.119.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>packages\SkiaSharp.Views.Desktop.Common.3.119.0\lib\net462\SkiaSharp.Views.Desktop.Common.dll</HintPath>
     </Reference>
-    <Reference Include="SkiaSharp.Views.WPF, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>packages\SkiaSharp.Views.WPF.2.88.9\lib\net462\SkiaSharp.Views.WPF.dll</HintPath>
+    <Reference Include="SkiaSharp.Views.WPF, Version=3.119.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>packages\SkiaSharp.Views.WPF.3.119.0\lib\net462\SkiaSharp.Views.WPF.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Buffers, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
@@ -179,8 +179,8 @@
       <HintPath>packages\System.IO.Pipelines.9.0.8\lib\net462\System.IO.Pipelines.dll</HintPath>
     </Reference>
     <Reference Include="System.Management" />
-    <Reference Include="System.Memory, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
-      <HintPath>packages\System.Memory.4.6.3\lib\net462\System.Memory.dll</HintPath>
+    <Reference Include="System.Memory, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>packages\System.Memory.4.6.2\lib\net462\System.Memory.dll</HintPath>
     </Reference>
     <Reference Include="System.Net.Http.Formatting, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>packages\Microsoft.AspNet.WebApi.Client.6.0.0\lib\net45\System.Net.Http.Formatting.dll</HintPath>
@@ -203,9 +203,6 @@
     <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
       <HintPath>packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
     </Reference>
-    <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
-      <HintPath>packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
-    </Reference>
     <Reference Include="System.Web" />
     <Reference Include="System.Web.Extensions" />
     <Reference Include="System.Web.Http, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -535,7 +532,7 @@
     <Resource Include="Fonts\Alibaba-PuHuiTi-Bold.ttf" />
     <Resource Include="Fonts\Alibaba-PuHuiTi-Regular.ttf" />
     <Resource Include="Fonts\Alibaba-PuHuiTi-Medium.ttf" />
-    <None Include="Converters\StringEmptyToVisibilityConverter.cs.bak" />
+    <None Include="OpenTK.dll.config" />
     <None Include="README.md" />
     <Resource Include="Resources\bucket.png">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -607,7 +604,6 @@
     <Content Include="Config\Config.json">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
-    <None Include="OpenTK.dll.config" />
     <None Include="packages.config" />
     <None Include="Properties\app.manifest" />
     <None Include="Properties\Settings.settings">
@@ -653,23 +649,19 @@
       <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
     </PropertyGroup>
     <Error Condition="!Exists('packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.119.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.119.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets'))" />
-    <Error Condition="!Exists('packages\EntityFramework.6.5.1\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\EntityFramework.6.5.1\build\EntityFramework.props'))" />
-    <Error Condition="!Exists('packages\EntityFramework.6.5.1\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\EntityFramework.6.5.1\build\EntityFramework.targets'))" />
-    <Error Condition="!Exists('packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets'))" />
-    <Error Condition="!Exists('packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets'))" />
-    <Error Condition="!Exists('packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets'))" />
-    <Error Condition="!Exists('packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets'))" />
-    <Error Condition="!Exists('packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets'))" />
-    <Error Condition="!Exists('packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets'))" />
+    <Error Condition="!Exists('packages\EntityFramework.6.5.2\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\EntityFramework.6.5.2\build\EntityFramework.props'))" />
+    <Error Condition="!Exists('packages\EntityFramework.6.5.2\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\EntityFramework.6.5.2\build\EntityFramework.targets'))" />
+    <Error Condition="!Exists('packages\SkiaSharp.NativeAssets.Linux.NoDependencies.3.119.0\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\SkiaSharp.NativeAssets.Linux.NoDependencies.3.119.0\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets'))" />
+    <Error Condition="!Exists('packages\SkiaSharp.NativeAssets.macOS.3.119.0\build\net462\SkiaSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\SkiaSharp.NativeAssets.macOS.3.119.0\build\net462\SkiaSharp.NativeAssets.macOS.targets'))" />
+    <Error Condition="!Exists('packages\SkiaSharp.NativeAssets.Win32.3.119.0\build\net462\SkiaSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\SkiaSharp.NativeAssets.Win32.3.119.0\build\net462\SkiaSharp.NativeAssets.Win32.targets'))" />
     <Error Condition="!Exists('packages\QuestPDF.2025.7.1\build\net4\QuestPDF.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\QuestPDF.2025.7.1\build\net4\QuestPDF.targets'))" />
+    <Error Condition="!Exists('packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets'))" />
   </Target>
   <Import Project="packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.119.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets" Condition="Exists('packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.119.0\build\net46\Stub.System.Data.SQLite.Core.NetFramework.targets')" />
-  <Import Project="packages\EntityFramework.6.5.1\build\EntityFramework.targets" Condition="Exists('packages\EntityFramework.6.5.1\build\EntityFramework.targets')" />
-  <Import Project="packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets" Condition="Exists('packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" />
-  <Import Project="packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets" Condition="Exists('packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets')" />
-  <Import Project="packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets" Condition="Exists('packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets')" />
-  <Import Project="packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets" Condition="Exists('packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets')" />
-  <Import Project="packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets" Condition="Exists('packages\HarfBuzzSharp.NativeAssets.Linux.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Linux.targets')" />
-  <Import Project="packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets" Condition="Exists('packages\SkiaSharp.NativeAssets.Linux.NoDependencies.2.88.9\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" />
+  <Import Project="packages\EntityFramework.6.5.2\build\EntityFramework.targets" Condition="Exists('packages\EntityFramework.6.5.2\build\EntityFramework.targets')" />
+  <Import Project="packages\SkiaSharp.NativeAssets.Linux.NoDependencies.3.119.0\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets" Condition="Exists('packages\SkiaSharp.NativeAssets.Linux.NoDependencies.3.119.0\build\net462\SkiaSharp.NativeAssets.Linux.NoDependencies.targets')" />
+  <Import Project="packages\SkiaSharp.NativeAssets.macOS.3.119.0\build\net462\SkiaSharp.NativeAssets.macOS.targets" Condition="Exists('packages\SkiaSharp.NativeAssets.macOS.3.119.0\build\net462\SkiaSharp.NativeAssets.macOS.targets')" />
+  <Import Project="packages\SkiaSharp.NativeAssets.Win32.3.119.0\build\net462\SkiaSharp.NativeAssets.Win32.targets" Condition="Exists('packages\SkiaSharp.NativeAssets.Win32.3.119.0\build\net462\SkiaSharp.NativeAssets.Win32.targets')" />
   <Import Project="packages\QuestPDF.2025.7.1\build\net4\QuestPDF.targets" Condition="Exists('packages\QuestPDF.2025.7.1\build\net4\QuestPDF.targets')" />
+  <Import Project="packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets" Condition="Exists('packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets')" />
 </Project>

+ 12 - 2
Styles/Styles.xaml

@@ -134,13 +134,23 @@
         <Setter Property="pu:TextBoxHelper.CornerRadius" Value="4"/>
         <Setter Property="pu:TextBoxHelper.HoverBorderBrush" Value="#6158E5"/>
     </Style>
+     
     <Style TargetType="pu:NumberInput" BasedOn="{StaticResource {x:Type pu:NumberInput}}">
-        <Setter Property="Height" Value="30"/>
-        <Setter Property="BorderBrush" Value="#FFC9CCD4"/>
+        <Setter Property="Height" Value="40"/>
+        <Setter Property="Width" Value="150"/>
+        <Setter Property="Background" Value="#202045"/>
+        <Setter Property="BorderBrush" Value="#3B3B7B"/>
+        <Setter Property="BorderThickness" Value="2,2,2,2"/>
+        <Setter Property="Foreground" Value="#FFFFFF"/>
+        <Setter Property="Padding" Value="6,3"/>
+        <Setter Property="FontSize" Value="18"/>
+        <Setter Property="HorizontalAlignment" Value="Center"/>
+        <Setter Property="IsSnapToIntervalEnabled" Value="False"/>
         <Setter Property="pu:NumberInput.CornerRadius" Value="5"/>
         <Setter Property="pu:NumberInput.FocusedShadowColor" Value="#FFDEE8F8"/>
         <Setter Property="pu:NumberInput.WatermarkForeground" Value="#CCCCCC"/>
         <Setter Property="pu:NumberInput.HoverBorderBrush" Value="#6158E5"/>
+        <Setter Property="pu:NumberInput.UpDownButtonVisibility" Value="Collapsed"/>
     </Style>
     <Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
         <Setter Property="Foreground" Value="#7886B2"/>

+ 273 - 0
UpgradeLog.htm

@@ -0,0 +1,273 @@
+<!DOCTYPE html>
+<!-- saved from url=(0014)about:internet -->
+ <html xmlns:msxsl="urn:schemas-microsoft-com:xslt"><head><meta content="en-us" http-equiv="Content-Language" /><meta content="text/html; charset=utf-16" http-equiv="Content-Type" /><title _locID="ConversionReport0">
+          迁移报告
+        </title><style> 
+                    /* Body style, for the entire document */
+                    body
+                    {
+                        background: #F3F3F4;
+                        color: #1E1E1F;
+                        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+                        padding: 0;
+                        margin: 0;
+                    }
+
+                    /* Header1 style, used for the main title */
+                    h1
+                    {
+                        padding: 10px 0px 10px 10px;
+                        font-size: 21pt;
+                        background-color: #E2E2E2;
+                        border-bottom: 1px #C1C1C2 solid; 
+                        color: #201F20;
+                        margin: 0;
+                        font-weight: normal;
+                    }
+
+                    /* Header2 style, used for "Overview" and other sections */
+                    h2
+                    {
+                        font-size: 18pt;
+                        font-weight: normal;
+                        padding: 15px 0 5px 0;
+                        margin: 0;
+                    }
+
+                    /* Header3 style, used for sub-sections, such as project name */
+                    h3
+                    {
+                        font-weight: normal;
+                        font-size: 15pt;
+                        margin: 0;
+                        padding: 15px 0 5px 0;
+                        background-color: transparent;
+                    }
+
+                    /* Color all hyperlinks one color */
+                    a
+                    {
+                        color: #1382CE;
+                    }
+
+                    /* Table styles */ 
+                    table
+                    {
+                        border-spacing: 0 0;
+                        border-collapse: collapse;
+                        font-size: 10pt;
+                    }
+
+                    table th
+                    {
+                        background: #E7E7E8;
+                        text-align: left;
+                        text-decoration: none;
+                        font-weight: normal;
+                        padding: 3px 6px 3px 6px;
+                    }
+
+                    table td
+                    {
+                        vertical-align: top;
+                        padding: 3px 6px 5px 5px;
+                        margin: 0px;
+                        border: 1px solid #E7E7E8;
+                        background: #F7F7F8;
+                    }
+
+                    /* Local link is a style for hyperlinks that link to file:/// content, there are lots so color them as 'normal' text until the user mouse overs */
+                    .localLink
+                    {
+                        color: #1E1E1F;
+                        background: #EEEEED;
+                        text-decoration: none;
+                    }
+
+                    .localLink:hover
+                    {
+                        color: #1382CE;
+                        background: #FFFF99;
+                        text-decoration: none;
+                    }
+
+                    /* Center text, used in the over views cells that contain message level counts */ 
+                    .textCentered
+                    {
+                        text-align: center;
+                    }
+
+                    /* The message cells in message tables should take up all avaliable space */
+                    .messageCell
+                    {
+                        width: 100%;
+                    }
+
+                    /* Padding around the content after the h1 */ 
+                    #content 
+                    {
+	                    padding: 0px 12px 12px 12px; 
+                    }
+
+                    /* The overview table expands to width, with a max width of 97% */ 
+                    #overview table
+                    {
+                        width: auto;
+                        max-width: 75%; 
+                    }
+
+                    /* The messages tables are always 97% width */
+                    #messages table
+                    {
+                        width: 97%;
+                    }
+
+                    /* All Icons */
+                    .IconSuccessEncoded, .IconInfoEncoded, .IconWarningEncoded, .IconErrorEncoded
+                    {
+                        min-width:18px;
+                        min-height:18px; 
+                        background-repeat:no-repeat;
+                        background-position:center;
+                    }
+
+                    /* Success icon encoded */
+                    .IconSuccessEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconSuccess#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABcElEQVR4Xq2TsUsCURzHv15g8ZJcBWlyiYYgCIWcb9DFRRwMW5TA2c0/QEFwFkxxUQdxVlBwCYWOi6IhWgQhBLHJUCkhLr/BW8S7gvrAg+N+v8/v+x68Z8MGy+XSCyABQAXgBgHGALoASkIIDWSLeLBetdHryMjd5IxQPWT4rn1c/P7+xxp72Cs9m5SZ0Bq2vPnbPFafK2zDvmNHypdC0BPkLlQhxJsCAhQoZwdZU5mwxh720qGo8MzTxTTKZDPCx2HoVzp6lz0Q9tKhyx0kGs8Ny+TkWRKk8lCROwEduhyg9l/6lunOPSfmH3NUH6uQ0KHLAe7JYvJjevm+DAMGJHToKtigE+vwvIidxLamb8IBY9e+C5LiXREkfho3TSd06HJA13/oh6T51MTsfQbHrsMynQ5dDihFjiK8JJAU9AKIWTp76dCVN7HWHrajmUEGvyF9nkbAE6gLIS7kTUyuf2gscLoJrElZo/Mvj+nPz/kLTmfnEwP3tB0AAAAASUVORK5CYII=);
+                    }
+
+                    /* Information icon encoded */
+                    .IconInfoEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconInformation#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR4Xs2TsUoDQRRF7wwoziokjZUKadInhdhukR9YP8DMX1hYW+QvdsXa/QHBbcXC7W0CamWTQnclFutceIQJwwaWNLlwm5k5d94M76mmaeCrrmsLYOocY12FcxZFUeozCqKqqgYA8uevv1H6VuPxcwlfk5N92KHBxfFeCSAxxswlYAW/Xr989x/mv9gkhtyMDhcAxgzRsp7flj8B/HF1RsMXq+NZMkopaHe7lbKxQUEIGbKsYNoGn969060hZBkQex/W8oRQwsQaW2o3Ago2SVcJUzAgY3N0lTCZZm+zPS8HB51gMmS1DEYyOz9acKO1D8JWTlafKIMxdhvlfdyT94Vv5h7P8Ky7nQzACmhvKq3zk3PjW9asz9D/1oigecsioooAAAAASUVORK5CYII=);
+                    }
+
+                    /* Warning icon encoded */
+                    .IconWarningEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconWarning#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAx0lEQVR4XpWSMQ7CMAxFf4xAyBMLCxMrO8dhaBcuwdCJS3RJBw7SA/QGTCxdWJgiQYWKXJWKIXHIlyw5lqr34tQgEOdcBsCOx5yZK3hCCKdYXneQkh4pEfqzLfu+wVDSyyzFoJjfz9NB+pAF+eizx2Vruts0k15mPgvS6GYvpVtQhB61IB/dk6AF6fS4Ben0uIX5odtFe8Q/eW1KvFeH4e8khT6+gm5B+t3juyDt7n0jpe+CANTd+oTUjN/U3yVaABnSUjFz/gFq44JaVSCXeQAAAABJRU5ErkJggg==);
+                    }
+
+                    /* Error icon encoded */
+                    .IconErrorEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconError#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4XqWTvUoEQRCE6wYPZUA80AfwAQz23uCMjA7MDRQEIzPBVEyNTQUFIw00vcQTTMzuAh/AxEQQT8HF/3G/oGGnEUGuoNnd6qoZuqltyKEsyzVJq5I6rnUp6SjGeGhESikzzlc1eL7opfuVbrqbU1Zw9NCgtQMaZpY0eNnaaL2fHusvTK5vKu7sjSS1Y4y3QUA6K3e3Mau5UFDyMP7tYF9o8cAHZv68vipoIJg971PZIZ5HiwdvYGGvFVFHmGmZ2MxwmQYPXubPl9Up0tfoMQGetXd6mRbvhBw+boZ6WF7Mbv1+GsHRk0fQmPAH1GfmZirbCfDJ61tw3Px8/8pZsPAG4jlVhcPgZ7adwNWBB68lkRQWFiTgFlbnLY3DGGM7izIJIyT/jjIvEJw6fdJTc6krDzh6aMwMP9bvDH4ADSsa9uSWVJkAAAAASUVORK5CYII=);
+                    }
+                 </style><script type="text/javascript" language="javascript"> 
+          
+            // Startup 
+            // Hook up the the loaded event for the document/window, to linkify the document content
+            var startupFunction = function() { linkifyElement("messages"); };
+            
+            if(window.attachEvent)
+            {
+              window.attachEvent('onload', startupFunction);
+            }
+            else if (window.addEventListener) 
+            {
+              window.addEventListener('load', startupFunction, false);
+            }
+            else 
+            {
+              document.addEventListener('load', startupFunction, false);
+            } 
+            
+            // Toggles the visibility of table rows with the specified name 
+            function toggleTableRowsByName(name)
+            {
+               var allRows = document.getElementsByTagName('tr');
+               for (i=0; i < allRows.length; i++)
+               {
+                  var currentName = allRows[i].getAttribute('name');
+                  if(!!currentName && currentName.indexOf(name) == 0)
+                  {
+                      var isVisible = allRows[i].style.display == ''; 
+                      isVisible ? allRows[i].style.display = 'none' : allRows[i].style.display = '';
+                  }
+               }
+            }
+            
+            function scrollToFirstVisibleRow(name) 
+            {
+               var allRows = document.getElementsByTagName('tr');
+               for (i=0; i < allRows.length; i++)
+               {
+                  var currentName = allRows[i].getAttribute('name');
+                  var isVisible = allRows[i].style.display == ''; 
+                  if(!!currentName && currentName.indexOf(name) == 0 && isVisible)
+                  {
+                     allRows[i].scrollIntoView(true); 
+                     return true; 
+                  }
+               }
+               
+               return false;
+            }
+            
+            // Linkifies the specified text content, replaces candidate links with html links 
+            function linkify(text)
+            {
+                 if(!text || 0 === text.length)
+                 {
+                     return text; 
+                 }
+
+                 // Find http, https and ftp links and replace them with hyper links 
+                 var urlLink = /(http|https|ftp)\:\/\/[a-zA-Z0-9\-\.]+(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._\?\,\/\\\+&%\$#\=~;\{\}])*/gi;
+                 
+                 return text.replace(urlLink, '<a href="$&">$&</a>') ;
+            }
+            
+            // Linkifies the specified element by ID
+            function linkifyElement(id)
+            {
+                var element = document.getElementById(id);
+                if(!!element)
+                {
+                  element.innerHTML = linkify(element.innerHTML); 
+                }
+            }
+            
+            function ToggleMessageVisibility(projectName)
+            {
+              if(!projectName || 0 === projectName.length)
+              {
+                return; 
+              }
+              
+              toggleTableRowsByName("MessageRowClass" + projectName);
+              toggleTableRowsByName('MessageRowHeaderShow' + projectName);
+              toggleTableRowsByName('MessageRowHeaderHide' + projectName); 
+            }
+            
+            function ScrollToFirstVisibleMessage(projectName)
+            {
+              if(!projectName || 0 === projectName.length)
+              {
+                return; 
+              }
+              
+              // First try the 'Show messages' row
+              if(!scrollToFirstVisibleRow('MessageRowHeaderShow' + projectName))
+              {
+                // Failed to find a visible row for 'Show messages', try an actual message row 
+                scrollToFirstVisibleRow('MessageRowClass' + projectName); 
+              }
+            }
+           </script></head><body><h1 _locID="ConversionReport">
+          迁移报告 - </h1><div id="content"><h2 _locID="OverviewTitle">概述</h2><div id="overview"><table><tr><th></th><th _locID="ProjectTableHeader">项目</th><th _locID="PathTableHeader">路径</th><th _locID="ErrorsTableHeader">错误</th><th _locID="WarningsTableHeader">警告</th><th _locID="MessagesTableHeader">消息</th></tr><tr><td class="IconErrorEncoded" /><td><strong><a href="#SWRIS">SWRIS</a></strong></td><td>SWRIS.csproj</td><td class="textCentered"><a href="#SWRISError">1</a></td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#">0</a></td></tr><tr><td class="IconSuccessEncoded" /><td><strong><a href="#Solution"><span _locID="OverviewSolutionSpan">解决方案</span></a></strong></td><td>SWRIS.sln</td><td class="textCentered"><a>0</a></td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#" onclick="ScrollToFirstVisibleMessage('Solution'); return false;">1</a></td></tr></table></div><h2 _locID="SolutionAndProjectsTitle">解决方案和项目</h2><div id="messages"><a name="SWRIS" /><h3>SWRIS</h3><table><tr id="SWRISHeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">消息</th></tr><tr name="ErrorRowClassSWRIS"><td class="IconErrorEncoded"><a name="SWRISError" /></td><td class="messageCell"><strong>SWRIS.csproj:
+        </strong><span>行 -2069067848 出错。应为“ENCODING”,却发现是“utf-8”。</span></td></tr></table><a name="Solution" /><h3 _locID="ProjectDisplayNameHeader">解决方案</h3><table><tr id="SolutionHeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">消息</th></tr><tr name="MessageRowHeaderShowSolution"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="ShowAdditionalMessages" href="#" name="SolutionMessage" onclick="ToggleMessageVisibility('Solution'); return false;">
+          显示 1 其他消息
+        </a></td></tr><tr name="MessageRowClassSolution" style="display: none"><td class="IconInfoEncoded"><a name="SolutionMessage" /></td><td class="messageCell"><strong>SWRIS.sln:
+        </strong><span>解决方案文件不需要迁移。</span></td></tr><tr style="display: none" name="MessageRowHeaderHideSolution"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="HideAdditionalMessages" href="#" name="SolutionMessage" onclick="ToggleMessageVisibility('Solution'); return false;">
+          隐藏 1 其他消息
+        </a></td></tr></table></div></div></body></html>

+ 273 - 0
UpgradeLog2.htm

@@ -0,0 +1,273 @@
+<!DOCTYPE html>
+<!-- saved from url=(0014)about:internet -->
+ <html xmlns:msxsl="urn:schemas-microsoft-com:xslt"><head><meta content="en-us" http-equiv="Content-Language" /><meta content="text/html; charset=utf-16" http-equiv="Content-Type" /><title _locID="ConversionReport0">
+          迁移报告
+        </title><style> 
+                    /* Body style, for the entire document */
+                    body
+                    {
+                        background: #F3F3F4;
+                        color: #1E1E1F;
+                        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+                        padding: 0;
+                        margin: 0;
+                    }
+
+                    /* Header1 style, used for the main title */
+                    h1
+                    {
+                        padding: 10px 0px 10px 10px;
+                        font-size: 21pt;
+                        background-color: #E2E2E2;
+                        border-bottom: 1px #C1C1C2 solid; 
+                        color: #201F20;
+                        margin: 0;
+                        font-weight: normal;
+                    }
+
+                    /* Header2 style, used for "Overview" and other sections */
+                    h2
+                    {
+                        font-size: 18pt;
+                        font-weight: normal;
+                        padding: 15px 0 5px 0;
+                        margin: 0;
+                    }
+
+                    /* Header3 style, used for sub-sections, such as project name */
+                    h3
+                    {
+                        font-weight: normal;
+                        font-size: 15pt;
+                        margin: 0;
+                        padding: 15px 0 5px 0;
+                        background-color: transparent;
+                    }
+
+                    /* Color all hyperlinks one color */
+                    a
+                    {
+                        color: #1382CE;
+                    }
+
+                    /* Table styles */ 
+                    table
+                    {
+                        border-spacing: 0 0;
+                        border-collapse: collapse;
+                        font-size: 10pt;
+                    }
+
+                    table th
+                    {
+                        background: #E7E7E8;
+                        text-align: left;
+                        text-decoration: none;
+                        font-weight: normal;
+                        padding: 3px 6px 3px 6px;
+                    }
+
+                    table td
+                    {
+                        vertical-align: top;
+                        padding: 3px 6px 5px 5px;
+                        margin: 0px;
+                        border: 1px solid #E7E7E8;
+                        background: #F7F7F8;
+                    }
+
+                    /* Local link is a style for hyperlinks that link to file:/// content, there are lots so color them as 'normal' text until the user mouse overs */
+                    .localLink
+                    {
+                        color: #1E1E1F;
+                        background: #EEEEED;
+                        text-decoration: none;
+                    }
+
+                    .localLink:hover
+                    {
+                        color: #1382CE;
+                        background: #FFFF99;
+                        text-decoration: none;
+                    }
+
+                    /* Center text, used in the over views cells that contain message level counts */ 
+                    .textCentered
+                    {
+                        text-align: center;
+                    }
+
+                    /* The message cells in message tables should take up all avaliable space */
+                    .messageCell
+                    {
+                        width: 100%;
+                    }
+
+                    /* Padding around the content after the h1 */ 
+                    #content 
+                    {
+	                    padding: 0px 12px 12px 12px; 
+                    }
+
+                    /* The overview table expands to width, with a max width of 97% */ 
+                    #overview table
+                    {
+                        width: auto;
+                        max-width: 75%; 
+                    }
+
+                    /* The messages tables are always 97% width */
+                    #messages table
+                    {
+                        width: 97%;
+                    }
+
+                    /* All Icons */
+                    .IconSuccessEncoded, .IconInfoEncoded, .IconWarningEncoded, .IconErrorEncoded
+                    {
+                        min-width:18px;
+                        min-height:18px; 
+                        background-repeat:no-repeat;
+                        background-position:center;
+                    }
+
+                    /* Success icon encoded */
+                    .IconSuccessEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconSuccess#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABcElEQVR4Xq2TsUsCURzHv15g8ZJcBWlyiYYgCIWcb9DFRRwMW5TA2c0/QEFwFkxxUQdxVlBwCYWOi6IhWgQhBLHJUCkhLr/BW8S7gvrAg+N+v8/v+x68Z8MGy+XSCyABQAXgBgHGALoASkIIDWSLeLBetdHryMjd5IxQPWT4rn1c/P7+xxp72Cs9m5SZ0Bq2vPnbPFafK2zDvmNHypdC0BPkLlQhxJsCAhQoZwdZU5mwxh720qGo8MzTxTTKZDPCx2HoVzp6lz0Q9tKhyx0kGs8Ny+TkWRKk8lCROwEduhyg9l/6lunOPSfmH3NUH6uQ0KHLAe7JYvJjevm+DAMGJHToKtigE+vwvIidxLamb8IBY9e+C5LiXREkfho3TSd06HJA13/oh6T51MTsfQbHrsMynQ5dDihFjiK8JJAU9AKIWTp76dCVN7HWHrajmUEGvyF9nkbAE6gLIS7kTUyuf2gscLoJrElZo/Mvj+nPz/kLTmfnEwP3tB0AAAAASUVORK5CYII=);
+                    }
+
+                    /* Information icon encoded */
+                    .IconInfoEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconInformation#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR4Xs2TsUoDQRRF7wwoziokjZUKadInhdhukR9YP8DMX1hYW+QvdsXa/QHBbcXC7W0CamWTQnclFutceIQJwwaWNLlwm5k5d94M76mmaeCrrmsLYOocY12FcxZFUeozCqKqqgYA8uevv1H6VuPxcwlfk5N92KHBxfFeCSAxxswlYAW/Xr989x/mv9gkhtyMDhcAxgzRsp7flj8B/HF1RsMXq+NZMkopaHe7lbKxQUEIGbKsYNoGn969060hZBkQex/W8oRQwsQaW2o3Ago2SVcJUzAgY3N0lTCZZm+zPS8HB51gMmS1DEYyOz9acKO1D8JWTlafKIMxdhvlfdyT94Vv5h7P8Ky7nQzACmhvKq3zk3PjW9asz9D/1oigecsioooAAAAASUVORK5CYII=);
+                    }
+
+                    /* Warning icon encoded */
+                    .IconWarningEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconWarning#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAx0lEQVR4XpWSMQ7CMAxFf4xAyBMLCxMrO8dhaBcuwdCJS3RJBw7SA/QGTCxdWJgiQYWKXJWKIXHIlyw5lqr34tQgEOdcBsCOx5yZK3hCCKdYXneQkh4pEfqzLfu+wVDSyyzFoJjfz9NB+pAF+eizx2Vruts0k15mPgvS6GYvpVtQhB61IB/dk6AF6fS4Ben0uIX5odtFe8Q/eW1KvFeH4e8khT6+gm5B+t3juyDt7n0jpe+CANTd+oTUjN/U3yVaABnSUjFz/gFq44JaVSCXeQAAAABJRU5ErkJggg==);
+                    }
+
+                    /* Error icon encoded */
+                    .IconErrorEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconError#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4XqWTvUoEQRCE6wYPZUA80AfwAQz23uCMjA7MDRQEIzPBVEyNTQUFIw00vcQTTMzuAh/AxEQQT8HF/3G/oGGnEUGuoNnd6qoZuqltyKEsyzVJq5I6rnUp6SjGeGhESikzzlc1eL7opfuVbrqbU1Zw9NCgtQMaZpY0eNnaaL2fHusvTK5vKu7sjSS1Y4y3QUA6K3e3Mau5UFDyMP7tYF9o8cAHZv68vipoIJg971PZIZ5HiwdvYGGvFVFHmGmZ2MxwmQYPXubPl9Up0tfoMQGetXd6mRbvhBw+boZ6WF7Mbv1+GsHRk0fQmPAH1GfmZirbCfDJ61tw3Px8/8pZsPAG4jlVhcPgZ7adwNWBB68lkRQWFiTgFlbnLY3DGGM7izIJIyT/jjIvEJw6fdJTc6krDzh6aMwMP9bvDH4ADSsa9uSWVJkAAAAASUVORK5CYII=);
+                    }
+                 </style><script type="text/javascript" language="javascript"> 
+          
+            // Startup 
+            // Hook up the the loaded event for the document/window, to linkify the document content
+            var startupFunction = function() { linkifyElement("messages"); };
+            
+            if(window.attachEvent)
+            {
+              window.attachEvent('onload', startupFunction);
+            }
+            else if (window.addEventListener) 
+            {
+              window.addEventListener('load', startupFunction, false);
+            }
+            else 
+            {
+              document.addEventListener('load', startupFunction, false);
+            } 
+            
+            // Toggles the visibility of table rows with the specified name 
+            function toggleTableRowsByName(name)
+            {
+               var allRows = document.getElementsByTagName('tr');
+               for (i=0; i < allRows.length; i++)
+               {
+                  var currentName = allRows[i].getAttribute('name');
+                  if(!!currentName && currentName.indexOf(name) == 0)
+                  {
+                      var isVisible = allRows[i].style.display == ''; 
+                      isVisible ? allRows[i].style.display = 'none' : allRows[i].style.display = '';
+                  }
+               }
+            }
+            
+            function scrollToFirstVisibleRow(name) 
+            {
+               var allRows = document.getElementsByTagName('tr');
+               for (i=0; i < allRows.length; i++)
+               {
+                  var currentName = allRows[i].getAttribute('name');
+                  var isVisible = allRows[i].style.display == ''; 
+                  if(!!currentName && currentName.indexOf(name) == 0 && isVisible)
+                  {
+                     allRows[i].scrollIntoView(true); 
+                     return true; 
+                  }
+               }
+               
+               return false;
+            }
+            
+            // Linkifies the specified text content, replaces candidate links with html links 
+            function linkify(text)
+            {
+                 if(!text || 0 === text.length)
+                 {
+                     return text; 
+                 }
+
+                 // Find http, https and ftp links and replace them with hyper links 
+                 var urlLink = /(http|https|ftp)\:\/\/[a-zA-Z0-9\-\.]+(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._\?\,\/\\\+&%\$#\=~;\{\}])*/gi;
+                 
+                 return text.replace(urlLink, '<a href="$&">$&</a>') ;
+            }
+            
+            // Linkifies the specified element by ID
+            function linkifyElement(id)
+            {
+                var element = document.getElementById(id);
+                if(!!element)
+                {
+                  element.innerHTML = linkify(element.innerHTML); 
+                }
+            }
+            
+            function ToggleMessageVisibility(projectName)
+            {
+              if(!projectName || 0 === projectName.length)
+              {
+                return; 
+              }
+              
+              toggleTableRowsByName("MessageRowClass" + projectName);
+              toggleTableRowsByName('MessageRowHeaderShow' + projectName);
+              toggleTableRowsByName('MessageRowHeaderHide' + projectName); 
+            }
+            
+            function ScrollToFirstVisibleMessage(projectName)
+            {
+              if(!projectName || 0 === projectName.length)
+              {
+                return; 
+              }
+              
+              // First try the 'Show messages' row
+              if(!scrollToFirstVisibleRow('MessageRowHeaderShow' + projectName))
+              {
+                // Failed to find a visible row for 'Show messages', try an actual message row 
+                scrollToFirstVisibleRow('MessageRowClass' + projectName); 
+              }
+            }
+           </script></head><body><h1 _locID="ConversionReport">
+          迁移报告 - </h1><div id="content"><h2 _locID="OverviewTitle">概述</h2><div id="overview"><table><tr><th></th><th _locID="ProjectTableHeader">项目</th><th _locID="PathTableHeader">路径</th><th _locID="ErrorsTableHeader">错误</th><th _locID="WarningsTableHeader">警告</th><th _locID="MessagesTableHeader">消息</th></tr><tr><td class="IconErrorEncoded" /><td><strong><a href="#SWRIS">SWRIS</a></strong></td><td>SWRIS.csproj</td><td class="textCentered"><a href="#SWRISError">1</a></td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#">0</a></td></tr><tr><td class="IconSuccessEncoded" /><td><strong><a href="#Solution"><span _locID="OverviewSolutionSpan">解决方案</span></a></strong></td><td>SWRIS.sln</td><td class="textCentered"><a>0</a></td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#" onclick="ScrollToFirstVisibleMessage('Solution'); return false;">1</a></td></tr></table></div><h2 _locID="SolutionAndProjectsTitle">解决方案和项目</h2><div id="messages"><a name="SWRIS" /><h3>SWRIS</h3><table><tr id="SWRISHeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">消息</th></tr><tr name="ErrorRowClassSWRIS"><td class="IconErrorEncoded"><a name="SWRISError" /></td><td class="messageCell"><strong>SWRIS.csproj:
+        </strong><span>行 218825344 出错。应为“ENCODING”,却发现是“utf-8”。</span></td></tr></table><a name="Solution" /><h3 _locID="ProjectDisplayNameHeader">解决方案</h3><table><tr id="SolutionHeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">消息</th></tr><tr name="MessageRowHeaderShowSolution"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="ShowAdditionalMessages" href="#" name="SolutionMessage" onclick="ToggleMessageVisibility('Solution'); return false;">
+          显示 1 其他消息
+        </a></td></tr><tr name="MessageRowClassSolution" style="display: none"><td class="IconInfoEncoded"><a name="SolutionMessage" /></td><td class="messageCell"><strong>SWRIS.sln:
+        </strong><span>解决方案文件不需要迁移。</span></td></tr><tr style="display: none" name="MessageRowHeaderHideSolution"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="HideAdditionalMessages" href="#" name="SolutionMessage" onclick="ToggleMessageVisibility('Solution'); return false;">
+          隐藏 1 其他消息
+        </a></td></tr></table></div></div></body></html>

+ 268 - 0
UpgradeLog3.htm

@@ -0,0 +1,268 @@
+<!DOCTYPE html>
+<!-- saved from url=(0014)about:internet -->
+ <html xmlns:msxsl="urn:schemas-microsoft-com:xslt"><head><meta content="en-us" http-equiv="Content-Language" /><meta content="text/html; charset=utf-16" http-equiv="Content-Type" /><title _locID="ConversionReport0">
+          迁移报告
+        </title><style> 
+                    /* Body style, for the entire document */
+                    body
+                    {
+                        background: #F3F3F4;
+                        color: #1E1E1F;
+                        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+                        padding: 0;
+                        margin: 0;
+                    }
+
+                    /* Header1 style, used for the main title */
+                    h1
+                    {
+                        padding: 10px 0px 10px 10px;
+                        font-size: 21pt;
+                        background-color: #E2E2E2;
+                        border-bottom: 1px #C1C1C2 solid; 
+                        color: #201F20;
+                        margin: 0;
+                        font-weight: normal;
+                    }
+
+                    /* Header2 style, used for "Overview" and other sections */
+                    h2
+                    {
+                        font-size: 18pt;
+                        font-weight: normal;
+                        padding: 15px 0 5px 0;
+                        margin: 0;
+                    }
+
+                    /* Header3 style, used for sub-sections, such as project name */
+                    h3
+                    {
+                        font-weight: normal;
+                        font-size: 15pt;
+                        margin: 0;
+                        padding: 15px 0 5px 0;
+                        background-color: transparent;
+                    }
+
+                    /* Color all hyperlinks one color */
+                    a
+                    {
+                        color: #1382CE;
+                    }
+
+                    /* Table styles */ 
+                    table
+                    {
+                        border-spacing: 0 0;
+                        border-collapse: collapse;
+                        font-size: 10pt;
+                    }
+
+                    table th
+                    {
+                        background: #E7E7E8;
+                        text-align: left;
+                        text-decoration: none;
+                        font-weight: normal;
+                        padding: 3px 6px 3px 6px;
+                    }
+
+                    table td
+                    {
+                        vertical-align: top;
+                        padding: 3px 6px 5px 5px;
+                        margin: 0px;
+                        border: 1px solid #E7E7E8;
+                        background: #F7F7F8;
+                    }
+
+                    /* Local link is a style for hyperlinks that link to file:/// content, there are lots so color them as 'normal' text until the user mouse overs */
+                    .localLink
+                    {
+                        color: #1E1E1F;
+                        background: #EEEEED;
+                        text-decoration: none;
+                    }
+
+                    .localLink:hover
+                    {
+                        color: #1382CE;
+                        background: #FFFF99;
+                        text-decoration: none;
+                    }
+
+                    /* Center text, used in the over views cells that contain message level counts */ 
+                    .textCentered
+                    {
+                        text-align: center;
+                    }
+
+                    /* The message cells in message tables should take up all avaliable space */
+                    .messageCell
+                    {
+                        width: 100%;
+                    }
+
+                    /* Padding around the content after the h1 */ 
+                    #content 
+                    {
+	                    padding: 0px 12px 12px 12px; 
+                    }
+
+                    /* The overview table expands to width, with a max width of 97% */ 
+                    #overview table
+                    {
+                        width: auto;
+                        max-width: 75%; 
+                    }
+
+                    /* The messages tables are always 97% width */
+                    #messages table
+                    {
+                        width: 97%;
+                    }
+
+                    /* All Icons */
+                    .IconSuccessEncoded, .IconInfoEncoded, .IconWarningEncoded, .IconErrorEncoded
+                    {
+                        min-width:18px;
+                        min-height:18px; 
+                        background-repeat:no-repeat;
+                        background-position:center;
+                    }
+
+                    /* Success icon encoded */
+                    .IconSuccessEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconSuccess#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABcElEQVR4Xq2TsUsCURzHv15g8ZJcBWlyiYYgCIWcb9DFRRwMW5TA2c0/QEFwFkxxUQdxVlBwCYWOi6IhWgQhBLHJUCkhLr/BW8S7gvrAg+N+v8/v+x68Z8MGy+XSCyABQAXgBgHGALoASkIIDWSLeLBetdHryMjd5IxQPWT4rn1c/P7+xxp72Cs9m5SZ0Bq2vPnbPFafK2zDvmNHypdC0BPkLlQhxJsCAhQoZwdZU5mwxh720qGo8MzTxTTKZDPCx2HoVzp6lz0Q9tKhyx0kGs8Ny+TkWRKk8lCROwEduhyg9l/6lunOPSfmH3NUH6uQ0KHLAe7JYvJjevm+DAMGJHToKtigE+vwvIidxLamb8IBY9e+C5LiXREkfho3TSd06HJA13/oh6T51MTsfQbHrsMynQ5dDihFjiK8JJAU9AKIWTp76dCVN7HWHrajmUEGvyF9nkbAE6gLIS7kTUyuf2gscLoJrElZo/Mvj+nPz/kLTmfnEwP3tB0AAAAASUVORK5CYII=);
+                    }
+
+                    /* Information icon encoded */
+                    .IconInfoEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconInformation#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR4Xs2TsUoDQRRF7wwoziokjZUKadInhdhukR9YP8DMX1hYW+QvdsXa/QHBbcXC7W0CamWTQnclFutceIQJwwaWNLlwm5k5d94M76mmaeCrrmsLYOocY12FcxZFUeozCqKqqgYA8uevv1H6VuPxcwlfk5N92KHBxfFeCSAxxswlYAW/Xr989x/mv9gkhtyMDhcAxgzRsp7flj8B/HF1RsMXq+NZMkopaHe7lbKxQUEIGbKsYNoGn969060hZBkQex/W8oRQwsQaW2o3Ago2SVcJUzAgY3N0lTCZZm+zPS8HB51gMmS1DEYyOz9acKO1D8JWTlafKIMxdhvlfdyT94Vv5h7P8Ky7nQzACmhvKq3zk3PjW9asz9D/1oigecsioooAAAAASUVORK5CYII=);
+                    }
+
+                    /* Warning icon encoded */
+                    .IconWarningEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconWarning#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAx0lEQVR4XpWSMQ7CMAxFf4xAyBMLCxMrO8dhaBcuwdCJS3RJBw7SA/QGTCxdWJgiQYWKXJWKIXHIlyw5lqr34tQgEOdcBsCOx5yZK3hCCKdYXneQkh4pEfqzLfu+wVDSyyzFoJjfz9NB+pAF+eizx2Vruts0k15mPgvS6GYvpVtQhB61IB/dk6AF6fS4Ben0uIX5odtFe8Q/eW1KvFeH4e8khT6+gm5B+t3juyDt7n0jpe+CANTd+oTUjN/U3yVaABnSUjFz/gFq44JaVSCXeQAAAABJRU5ErkJggg==);
+                    }
+
+                    /* Error icon encoded */
+                    .IconErrorEncoded
+                    {
+                        /* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
+                        /* [---XsltValidateInternal-Base64EncodedImage:IconError#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
+                        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4XqWTvUoEQRCE6wYPZUA80AfwAQz23uCMjA7MDRQEIzPBVEyNTQUFIw00vcQTTMzuAh/AxEQQT8HF/3G/oGGnEUGuoNnd6qoZuqltyKEsyzVJq5I6rnUp6SjGeGhESikzzlc1eL7opfuVbrqbU1Zw9NCgtQMaZpY0eNnaaL2fHusvTK5vKu7sjSS1Y4y3QUA6K3e3Mau5UFDyMP7tYF9o8cAHZv68vipoIJg971PZIZ5HiwdvYGGvFVFHmGmZ2MxwmQYPXubPl9Up0tfoMQGetXd6mRbvhBw+boZ6WF7Mbv1+GsHRk0fQmPAH1GfmZirbCfDJ61tw3Px8/8pZsPAG4jlVhcPgZ7adwNWBB68lkRQWFiTgFlbnLY3DGGM7izIJIyT/jjIvEJw6fdJTc6krDzh6aMwMP9bvDH4ADSsa9uSWVJkAAAAASUVORK5CYII=);
+                    }
+                 </style><script type="text/javascript" language="javascript"> 
+          
+            // Startup 
+            // Hook up the the loaded event for the document/window, to linkify the document content
+            var startupFunction = function() { linkifyElement("messages"); };
+            
+            if(window.attachEvent)
+            {
+              window.attachEvent('onload', startupFunction);
+            }
+            else if (window.addEventListener) 
+            {
+              window.addEventListener('load', startupFunction, false);
+            }
+            else 
+            {
+              document.addEventListener('load', startupFunction, false);
+            } 
+            
+            // Toggles the visibility of table rows with the specified name 
+            function toggleTableRowsByName(name)
+            {
+               var allRows = document.getElementsByTagName('tr');
+               for (i=0; i < allRows.length; i++)
+               {
+                  var currentName = allRows[i].getAttribute('name');
+                  if(!!currentName && currentName.indexOf(name) == 0)
+                  {
+                      var isVisible = allRows[i].style.display == ''; 
+                      isVisible ? allRows[i].style.display = 'none' : allRows[i].style.display = '';
+                  }
+               }
+            }
+            
+            function scrollToFirstVisibleRow(name) 
+            {
+               var allRows = document.getElementsByTagName('tr');
+               for (i=0; i < allRows.length; i++)
+               {
+                  var currentName = allRows[i].getAttribute('name');
+                  var isVisible = allRows[i].style.display == ''; 
+                  if(!!currentName && currentName.indexOf(name) == 0 && isVisible)
+                  {
+                     allRows[i].scrollIntoView(true); 
+                     return true; 
+                  }
+               }
+               
+               return false;
+            }
+            
+            // Linkifies the specified text content, replaces candidate links with html links 
+            function linkify(text)
+            {
+                 if(!text || 0 === text.length)
+                 {
+                     return text; 
+                 }
+
+                 // Find http, https and ftp links and replace them with hyper links 
+                 var urlLink = /(http|https|ftp)\:\/\/[a-zA-Z0-9\-\.]+(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._\?\,\/\\\+&%\$#\=~;\{\}])*/gi;
+                 
+                 return text.replace(urlLink, '<a href="$&">$&</a>') ;
+            }
+            
+            // Linkifies the specified element by ID
+            function linkifyElement(id)
+            {
+                var element = document.getElementById(id);
+                if(!!element)
+                {
+                  element.innerHTML = linkify(element.innerHTML); 
+                }
+            }
+            
+            function ToggleMessageVisibility(projectName)
+            {
+              if(!projectName || 0 === projectName.length)
+              {
+                return; 
+              }
+              
+              toggleTableRowsByName("MessageRowClass" + projectName);
+              toggleTableRowsByName('MessageRowHeaderShow' + projectName);
+              toggleTableRowsByName('MessageRowHeaderHide' + projectName); 
+            }
+            
+            function ScrollToFirstVisibleMessage(projectName)
+            {
+              if(!projectName || 0 === projectName.length)
+              {
+                return; 
+              }
+              
+              // First try the 'Show messages' row
+              if(!scrollToFirstVisibleRow('MessageRowHeaderShow' + projectName))
+              {
+                // Failed to find a visible row for 'Show messages', try an actual message row 
+                scrollToFirstVisibleRow('MessageRowClass' + projectName); 
+              }
+            }
+           </script></head><body><h1 _locID="ConversionReport">
+          迁移报告 - </h1><div id="content"><h2 _locID="OverviewTitle">概述</h2><div id="overview"><table><tr><th></th><th _locID="ProjectTableHeader">项目</th><th _locID="PathTableHeader">路径</th><th _locID="ErrorsTableHeader">错误</th><th _locID="WarningsTableHeader">警告</th><th _locID="MessagesTableHeader">消息</th></tr><tr><td class="IconErrorEncoded" /><td><strong><a href="#SWRIS">SWRIS</a></strong></td><td>SWRIS.csproj</td><td class="textCentered"><a href="#SWRISError">1</a></td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#">0</a></td></tr></table></div><h2 _locID="SolutionAndProjectsTitle">解决方案和项目</h2><div id="messages"><a name="SWRIS" /><h3>SWRIS</h3><table><tr id="SWRISHeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">消息</th></tr><tr name="ErrorRowClassSWRIS"><td class="IconErrorEncoded"><a name="SWRISError" /></td><td class="messageCell"><strong>SWRIS.csproj:
+        </strong><span>行 -1918180096 出错。应为“ENCODING”,却发现是“utf-8”。</span></td></tr></table></div></div></body></html>

+ 21 - 21
packages.config

@@ -1,40 +1,40 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Dapper" version="2.1.66" targetFramework="net48" />
-  <package id="EntityFramework" version="6.5.1" targetFramework="net48" />
+  <package id="Dapper" version="2.1.79" targetFramework="net48" />
+  <package id="EntityFramework" version="6.5.2" targetFramework="net48" />
   <package id="EPPlus" version="4.5.3.3" targetFramework="net48" />
-  <package id="HarfBuzzSharp" version="7.3.0.3" targetFramework="net48" />
-  <package id="HarfBuzzSharp.NativeAssets.Linux" version="7.3.0.3" targetFramework="net48" />
-  <package id="HarfBuzzSharp.NativeAssets.macOS" version="7.3.0.3" targetFramework="net48" />
-  <package id="HarfBuzzSharp.NativeAssets.Win32" version="7.3.0.3" targetFramework="net48" />
-  <package id="HslCommunication" version="12.3.3" targetFramework="net48" />
+  <package id="HarfBuzzSharp" version="8.3.1.1" targetFramework="net48" />
+  <package id="HarfBuzzSharp.NativeAssets.Linux" version="8.3.1.1" targetFramework="net48" />
+  <package id="HarfBuzzSharp.NativeAssets.macOS" version="8.3.1.1" targetFramework="net48" />
+  <package id="HarfBuzzSharp.NativeAssets.Win32" version="8.3.1.1" targetFramework="net48" />
+  <package id="HslCommunication" version="12.9.2" targetFramework="net48" />
   <package id="Interop.IWshRuntimeLibrary" version="1.0.1" targetFramework="net48" />
   <package id="Microsoft.AspNet.WebApi.Client" version="6.0.0" targetFramework="net48" />
   <package id="Microsoft.AspNet.WebApi.Core" version="5.3.0" targetFramework="net48" />
   <package id="Microsoft.AspNet.WebApi.SelfHost" version="5.3.0" targetFramework="net48" />
-  <package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.8" targetFramework="net48" />
+  <package id="Microsoft.Bcl.AsyncInterfaces" version="10.0.8" targetFramework="net48" />
   <package id="Microsoft.Bcl.HashCode" version="1.1.1" targetFramework="net48" />
   <package id="Microsoft-WindowsAPICodePack-Core" version="1.1.5" targetFramework="net48" />
   <package id="Microsoft-WindowsAPICodePack-Shell" version="1.1.5" targetFramework="net48" />
-  <package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
+  <package id="Newtonsoft.Json" version="13.0.4" targetFramework="net48" />
   <package id="Newtonsoft.Json.Bson" version="1.0.3" targetFramework="net48" />
   <package id="OpenTK" version="3.3.1" targetFramework="net48" />
   <package id="OpenTK.GLWpfControl" version="3.3.0" targetFramework="net48" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net48" />
   <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net48" />
-  <package id="QRCoder" version="1.6.0" targetFramework="net48" />
+  <package id="QRCoder" version="1.8.0" targetFramework="net48" />
   <package id="QuestPDF" version="2025.7.1" targetFramework="net48" />
   <package id="RBush.Signed" version="4.0.0" targetFramework="net48" />
-  <package id="ScottPlot" version="5.0.55" targetFramework="net48" />
-  <package id="ScottPlot.WPF" version="5.0.55" targetFramework="net48" />
+  <package id="ScottPlot" version="5.1.59" targetFramework="net48" />
+  <package id="ScottPlot.WPF" version="5.1.59" targetFramework="net48" />
   <package id="SixLabors.Fonts" version="1.0.0" targetFramework="net48" />
-  <package id="SkiaSharp" version="2.88.9" targetFramework="net48" />
-  <package id="SkiaSharp.HarfBuzz" version="2.88.9" targetFramework="net48" />
-  <package id="SkiaSharp.NativeAssets.Linux.NoDependencies" version="2.88.9" targetFramework="net48" />
-  <package id="SkiaSharp.NativeAssets.macOS" version="2.88.9" targetFramework="net48" />
-  <package id="SkiaSharp.NativeAssets.Win32" version="2.88.9" targetFramework="net48" />
-  <package id="SkiaSharp.Views.Desktop.Common" version="2.88.9" targetFramework="net48" />
-  <package id="SkiaSharp.Views.WPF" version="2.88.9" targetFramework="net48" />
+  <package id="SkiaSharp" version="3.119.0" targetFramework="net48" />
+  <package id="SkiaSharp.HarfBuzz" version="3.119.0" targetFramework="net48" />
+  <package id="SkiaSharp.NativeAssets.Linux.NoDependencies" version="3.119.0" targetFramework="net48" />
+  <package id="SkiaSharp.NativeAssets.macOS" version="3.119.0" targetFramework="net48" />
+  <package id="SkiaSharp.NativeAssets.Win32" version="3.119.0" targetFramework="net48" />
+  <package id="SkiaSharp.Views.Desktop.Common" version="3.119.0" targetFramework="net48" />
+  <package id="SkiaSharp.Views.WPF" version="3.119.0" targetFramework="net48" />
   <package id="Stub.System.Data.SQLite.Core.NetFramework" version="1.0.119.0" targetFramework="net48" />
   <package id="System.Buffers" version="4.6.1" targetFramework="net48" />
   <package id="System.ComponentModel.Annotations" version="5.0.0" targetFramework="net48" />
@@ -44,12 +44,12 @@
   <package id="System.Data.SQLite.Linq" version="1.0.119.0" targetFramework="net48" />
   <package id="System.Drawing.Common" version="4.7.3" targetFramework="net48" />
   <package id="System.IO.Pipelines" version="9.0.8" targetFramework="net48" />
-  <package id="System.Memory" version="4.6.3" targetFramework="net48" />
+  <package id="System.Memory" version="4.6.2" targetFramework="net48" />
   <package id="System.Numerics.Vectors" version="4.6.1" targetFramework="net48" />
   <package id="System.Runtime.CompilerServices.Unsafe" version="6.1.2" targetFramework="net48" />
   <package id="System.Speech" version="10.0.0" targetFramework="net48" />
   <package id="System.Text.Encodings.Web" version="9.0.8" targetFramework="net48" />
   <package id="System.Text.Json" version="9.0.8" targetFramework="net48" />
   <package id="System.Threading.Tasks.Extensions" version="4.6.3" targetFramework="net48" />
-  <package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
+  <package id="System.ValueTuple" version="4.6.1" targetFramework="net48" />
 </packages>