You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#调用System.Windows.Forms时出现类型加载异常问题咨询

Unity中使用System.Windows.Forms触发类型加载异常的解决方案

这个问题我之前帮好几个Unity开发者解决过,本质是System.Windows.Forms是Windows桌面专属的UI组件,而Unity默认的运行时环境(不管是旧版的Mono还是新版的.NET后端)并没有默认包含这个库,再加上Unity的线程模型和WinForms不兼容,才会触发类型加载异常。下面给你几个靠谱的解决方向:

方案1:改用Unity原生/跨平台文件对话框(推荐)

这是最稳妥的方式,既能避免平台兼容性问题,又符合Unity的运行逻辑。

编辑器环境下(开发阶段用)

用Unity自带的EditorUtility.SaveFilePanel,完全适配编辑器环境:

using UnityEditor;
using UnityEngine;
using System.IO;

namespace BuildShare
{
    public static class BuildSaveHandler
    {
        public static void ExportSaveToFile(Build.BuildSave save)
        {
            // 弹出Unity原生的保存对话框
            string savePath = EditorUtility.SaveFilePanel(
                "导出存档文件",
                Application.persistentDataPath, // 默认打开存档目录
                $"{save.saveName}.txt",
                "txt");
            
            if (!string.IsNullOrEmpty(savePath))
            {
                using (StreamWriter writer = new StreamWriter(savePath))
                {
                    // 这里替换成你的存档写入逻辑
                    writer.WriteLine(save.ToString());
                }
            }
        }
    }
}

运行时环境(发布后用)

如果是跨平台发布,推荐用第三方跨平台文件对话框插件(Asset Store有很多免费的);如果只针对Windows平台,可以用Unity自带的UnityEngine.Windows.Dialogs:

using UnityEngine;
using UnityEngine.Windows.Dialogs;
using System.IO;

namespace BuildShare
{
    public static class BuildSaveHandler
    {
        public static void ExportSaveToFile(Build.BuildSave save)
        {
            FilePicker filePicker = new FilePicker();
            filePicker.mode = FilePickerMode.Save;
            filePicker.filter = "Text files (*.txt)|*.txt";
            filePicker.defaultFilename = $"{save.saveName}.txt";
            
            filePicker.Show(result =>
            {
                if (result == FilePickerResult.OK && !string.IsNullOrEmpty(filePicker.filePath))
                {
                    using (StreamWriter writer = new StreamWriter(filePicker.filePath))
                    {
                        // 写入存档内容
                        writer.WriteLine(save.ToString());
                    }
                }
            });
        }
    }
}

方案2:强行使用System.Windows.Forms(仅限Windows平台)

如果你一定要用WinForms的对话框,只能针对Windows平台发布,步骤如下:

  1. 修改Unity的API兼容级别
    打开Player Settings -> Other Settings -> Configuration,把Api Compatibility Level设置为**.NET Framework 4.x**(不要选.NET Core/.NET)。

  2. 添加System.Windows.Forms.dll引用
    找到你Unity安装目录下的对应dll,比如路径大概是:Unity\Hub\Editor\[你的Unity版本]\Editor\Data\MonoBleedingEdge\lib\mono\4.7.1-api\System.Windows.Forms.dll,把它复制到项目的Plugins文件夹里。

  3. 修复线程兼容问题
    WinForms需要在STA线程运行,而Unity主线程是MTA,所以要单独开线程调用对话框:

using System;
using System.Threading;
using System.Windows.Forms;
using UnityEngine;
using System.IO;

namespace BuildShare
{
    public static class BuildSaveHandler
    {
        public static void ExportSaveToFile(Build.BuildSave save)
        {
            string savePath = null;

            // 创建STA线程处理WinForms对话框
            Thread staThread = new Thread(() =>
            {
                SaveFileDialog saveDialog = new SaveFileDialog();
                saveDialog.FileName = $"{save.saveName}.txt";
                saveDialog.Filter = "Text File | *.txt";
                
                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    savePath = saveDialog.FileName;
                }
            });
            
            staThread.SetApartmentState(ApartmentState.STA);
            staThread.Start();
            staThread.Join(); // 等待线程结束,获取保存路径

            if (!string.IsNullOrEmpty(savePath))
            {
                using (StreamWriter writer = new StreamWriter(savePath))
                {
                    // 写入存档内容
                    writer.WriteLine(save.ToString());
                }
            }
        }
    }
}
  1. 添加平台判断
    为了避免跨平台发布报错,用预处理指令包裹WinForms相关代码:
#if UNITY_STANDALONE_WIN
// 这里放WinForms相关的代码
#endif

额外注意事项

  • 不要在Unity主线程直接调用WinForms UI,线程模型不兼容会导致崩溃或异常;
  • 编辑器下尽量用Unity原生的对话框,WinForms窗口可能会出现焦点丢失、无法关闭的问题;
  • 如果选择方案2,你的项目只能在Windows平台运行,跨平台发布时会报错。

内容的提问来源于stack exchange,提问作者Maximillion Billiony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:42:36