博客 / 詳情

返回

dotnet 10 已知問題 WinForms 的 TargetFramework 與 System.Drawing.Common 不匹配將拋出找不到類型異常

此問題我已經在 WinForms 倉庫反饋: https://github.com/dotnet/winforms/issues/14145

最簡復現步驟如下:

先創建一個空的 .NET 項目,編輯 csproj 文件,替換為以下代碼

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0-windows</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="System.Drawing.Common" Version="10.0.1" />
  </ItemGroup>
</Project>

創建 Program.cs 文件,添加如下代碼

System.Windows.Forms.SendKeys.SendWait("Hello, World!");

將項目裏面的其餘文件全刪掉。然後構建運行項目

此時可見拋出如下錯誤

System.TypeInitializationException: The type initializer for 'System.Windows.Forms.SendKeys' threw an exception.
   ---> System.TypeInitializationException: The type initializer for 'System.Windows.Forms.ScaleHelper' threw an exception.
   ---> System.TypeLoadException: Could not load type 'System.Private.Windows.Core.OsVersion' from assembly 'System.Private.Windows.Core, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
     at System.Windows.Forms.ScaleHelper.<InitializeStatics>g__GetPerMonitorAware|8_1()
     at System.Windows.Forms.ScaleHelper.InitializeStatics()
     --- End of inner exception stack trace ---
     at System.Windows.Forms.ScaleHelper.get_InitialSystemDpi()
     at System.Windows.Forms.Control..ctor(Boolean autoInstallSyncContext)
     at System.Windows.Forms.SendKeys.SKWindow..ctor()
     at System.Windows.Forms.SendKeys..cctor()
     --- End of inner exception stack trace ---
     at System.Windows.Forms.SendKeys.SendWait(String keys)
     at sendkey_error.MainWindow.Button_Click(Object sender, RoutedEventArgs e)

問題的原因是在 https://github.com/dotnet/winforms/pull/12839 裏面修改了命名空間

這就導致了 OsVersion 類型從 System.Private.Windows.Core 命名空間改到 System.Private.Windows 命名空間,這裏的不匹配就導致了類型找不到異常

本次問題屬於情有可原,畢竟更新的是主版本號,主版本更新發生不兼容是合理的

此問題一開始是在 WPF 倉庫報告的,但經過我調查,和 WPF 毫無關係,詳細請看: https://github.com/dotnet/wpf/issues/11313

解決方法十分簡單,保持 System.Drawing.Common 跟隨主入口項目的 TargetFramework 版本,如修改 csproj 為如下代碼

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0-windows</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="System.Drawing.Common" Version="9.0.11" />
  </ItemGroup>
</Project>

本文代碼放在 github 和 gitee 上,可以使用如下命令行拉取代碼。我整個代碼倉庫比較龐大,使用以下命令行可以進行部分拉取,拉取速度比較快

先創建一個空文件夾,接着使用命令行 cd 命令進入此空文件夾,在命令行裏面輸入以下代碼,即可獲取到本文的代碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 1534db9e5f807d2c958cc8f7509f9f45229651e5

以上使用的是國內的 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令行繼續輸入以下代碼,將 gitee 源換成 github 源進行拉取代碼。如果依然拉取不到代碼,可以發郵件向我要代碼

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 1534db9e5f807d2c958cc8f7509f9f45229651e5

獲取代碼之後,進入 WPFDemo/LaiwerelawkewaFeereajemle 文件夾,即可獲取到源代碼

更多技術博客,請參閲 博客導航

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.