Skip to main content

Legacy Migration Guide (.NET Framework → .NET 8)

This document is based on the actual migration experience of InspectionHost (.NET Framework 4.8 → .NET 8), summarizing the migration path, considerations, and common issues.

1. Applicable Projects

ProjectCurrent VersionMigration Status
Leyu.InspectionHost.NET 4.8 → .NET 8✅ Completed (LEY-59)
Walton Line1/2/3.NET 4.5 / VS 2015Not planned
ENR_DUC.NET 4.8Not planned

2. Pre-Migration Assessment Checklist

2.1 Third-Party SDK Compatibility

StatusSDKNotes
Delta DIASECS (netcoreapp3.1)Fully compatible with .NET 8
⚠️KGS Common (.NET 4.5)Requires .NET 8 compatibility testing
⚠️Adlink Motion (Native P/Invoke)Requires x64 DLL verification
CommunityToolkit.MvvmNative .NET 8 support
HandyControl / LiveCharts2NuGet versions available

2.2 UI Framework

FromToComplexity
WinForms → WPFUI rewrite required (High)Recommended for new projects to use WPF directly
WinForms → WinForms (.NET 8)Only update project format (Low)Preserves existing UI

3. .csproj Format Conversion

3.1 Before: Legacy Format (631 lines)

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<LangVersion>7.3</LangVersion>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<!-- One PropertyGroup per Configuration|Platform -->
<!-- Each file manually listed as <Compile>, <EmbeddedResource>, <None> -->

<Reference Include="Newtonsoft.Json, Version=6.0.0.0, ...">
<HintPath>..\Dll\Newtonsoft.Json.dll</HintPath>
</Reference>
</Project>

3.2 After: SDK-style Format (38 lines)

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<Nullable>disable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.*" />
<PackageReference Include="HandyControl" Version="3.5.1" />
</ItemGroup>
</Project>

3.3 Key Differences

Aspect.NET Framework.NET 8 SDK-style
File enumerationManual <Compile> for each fileAuto globbing (*.cs)
Dependencies<Reference> + HintPath<PackageReference> NuGet
Platform configSeparate for each Config|PlatformSingle <TargetFramework>
Output pathManual <OutputPath>Automatic (bin/Release/net8.0-windows/)

4. Dependency Management Migration

4.1 NuGet Package Upgrades

Old (DLL Reference)New (NuGet)
Newtonsoft.Json 6.0.0 (local DLL)<PackageReference Include="Newtonsoft.Json" Version="13.*" />
M2Mqtt.Net 4.3.0 (local DLL)Evaluate alternative packages (MQTTnet)
System.Data.SQLite (local DLL)<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.*" />

4.2 Native DLL Handling

Unmanaged DLLs remain as <None> + CopyToOutputDirectory:

<!-- Managed DLL reference -->
<ItemGroup>
<Reference Include="DIASECS">
<HintPath>..\..\lib\DIASECS.dll</HintPath>
</Reference>
</ItemGroup>

<!-- Unmanaged Native DLL (no Reference needed) -->
<ItemGroup>
<None Include="..\..\lib\hasp_net_core.dll" CopyToOutputDirectory="PreserveNewest" />
<None Include="..\..\lib\hasp_windows_x64_24160.dll" CopyToOutputDirectory="PreserveNewest" />

<!-- Preserve subdirectory structure -->
<None Include="..\..\lib\cpsrt\win\x64\cpsrt.dll"
CopyToOutputDirectory="PreserveNewest"
Link="cpsrt\win\x64\cpsrt.dll" />
</ItemGroup>

The Link attribute preserves the subdirectory structure of Native DLLs.

5. MVVM Modernization

5.1 Before: Manual INotifyPropertyChanged

public class ViewModel : INotifyPropertyChanged
{
private string _status;
public string Status
{
get => _status;
set
{
if (_status != value)
{
_status = value;
OnPropertyChanged(nameof(Status));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

5.2 After: Source Generator

public partial class ViewModel : ObservableObject
{
[ObservableProperty]
private string _status;
// 自動產生 Status property + PropertyChanged 通知
}

Code volume reduced by ~70%.

6. DI Integration

6.1 Before: No DI (Manual Instantiation or ServiceLocator)

var service = new SecsService();  // 直接 new

6.2 After: Microsoft.Extensions.DependencyInjection

var services = new ServiceCollection();

// Mock/Real 切換
if (useRealSecs)
services.AddSingleton<ISecsHostService, SecsHostService>();
else
services.AddSingleton<ISecsHostService, MockSecsHostService>();

services.AddSingleton<MainViewModel>();

var provider = services.BuildServiceProvider();
var mainWindow = provider.GetRequiredService<MainWindow>();
mainWindow.DataContext = provider.GetRequiredService<MainViewModel>();

7. Nullable Reference Types

Recommended to disable during the initial migration phase to avoid a large number of warnings:

<Nullable>disable</Nullable>

Gradually enable and fix later.

8. Async Patterns

8.1 Before: Synchronous Blocking

public void Connect()
{
_driver.Init();
_driver.Start(); // 阻塞 UI Thread
}

8.2 After: Task-based Async

public Task ConnectAsync(string eqIp, string eqPort)
{
return Task.Run(() =>
{
_driver.Init();
_driver.Start();
});
}

9. Migration Step Checklist

  1. Create a new SDK-style .csproj (<Project Sdk="Microsoft.NET.Sdk">)
  2. Set TargetFramework: net8.0-windows (add -windows for WPF/WinForms)
  3. Migrate dependencies: <Reference><PackageReference>
  4. Handle Native DLLs: <None ... CopyToOutputDirectory="PreserveNewest" />
  5. Configure Nullable: disable initially
  6. Update MVVM: Manual Property → [ObservableProperty]
  7. Introduce DI: Microsoft.Extensions.DependencyInjection
  8. Async conversion: Synchronous blocking → async/await
  9. Test SDK compatibility: Verify third-party SDKs one by one
  10. Build verification: dotnet build + dotnet run

10. InspectionHost Migration Experience

ItemResult
Delta DIASECS SDK✅ netcoreapp3.1 DLL fully compatible with .NET 8
HASP / CodeMeter Licensing✅ Native DLL works correctly via <None> + Link
WinForms → WPF✅ Full rewrite (with HandyControl Dark Theme)
DI Introduction✅ Mock/Real SECS dual-mode switching
CommunityToolkit.Mvvm✅ Source Generator works correctly
.csproj631 lines → 38 lines

Document Version: v1.0 | Created: 2026-03-16 | Related Issue: GST-173