Unity使用 System.Windows.Forms 的问题

Posted 魔术师Dix

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity使用 System.Windows.Forms 的问题相关的知识,希望对你有一定的参考价值。

        因为最近开发需要用到使用 Windows 自带的窗口打开、文件选择等功能,然后兜兜转转需要使用  System.Windows.Forms 这个库。这个库在 WinForm 里是很常见的,但是要在 Unity 里使用,并打包出来还是有些坑的。

        我这里使用的 Unity 版本:2022.2.1f1c1

        PS:这个显然只能在PC上使用,想都不用想 ~

1、引入 System.Windows.Forms.dll

        首先这个 dll 不能从 vs 那里找,也就是 C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\…… 这个文件夹下面。这个导入进去用不了,会报错。

        只能使用Unity自带的,也就是在 :……Editor\\Data\\MonoBleedingEdge\\lib\\mono\\2.0-api 这个目录下面的 dll ,参考下文:

Unity-使用System.Windows.Forms.dll_慧眼圣贤心的博客-CSDN博客在Unity使用Windows窗体函数https://blog.csdn.net/pgw00k/article/details/53166861        因为我是Unity2022,所以没有 .Net 4.x 的选项,似乎那个选项并没有什么影响,都能正常跑。具体的使用方法是比较简单的:

using System.Windows.Forms;

public static void OpenWindowFolder()

    FolderBrowserDialog fbd = new FolderBrowserDialog();
    fbd.ShowDialog();

        就这样就完成了,在编辑器下运行效果如下:

         可以看到这个窗口的样式还是不知道哪个年代的窗口,然后语言也不是中文。不过无所谓,这个反正是测试用的,估计是可以在参数里设置的。


        但是用这个是用这个是有问题的(后面会详细说明),编辑器下是可以用的,但是打包出来有问题不能正常运行。后面的第2、3、4章节都是问题说明和解决思路,如不需要可以直接看第5小节的总结。


        

2、出包运行

        正常打包很容易就闪退了,很诡异(虽然有时候能出包)。我发现在 Build Setting 里把 Architecture 改成 Intel 32-bit 成功率就高了很多:

        

         实际上似乎不影响结果,就是单纯地打包成功率高一些而已,会减少一些报错和闪退的概率。

        但是运行起来就有问题了,会报空:

        显然是无法正常运行的,然后我上网去搜了一些解决方案。

 3、尝试使用csc.rsp解决

        首先测试了一下这个用 csc.rsp 来解决:

Unity 使用System.Windows.Forms.dll 库打包后,运行报错!_humilezr的博客-CSDN博客_unity dll打包程序运行不对好久没写博客了,年前接了一个项目,项目中需要为文件选择存储路径,然后就选择了比较常用的System.Windows.Forms.dll 库。 在Unity编辑器模式下没任何问题,但是打包后,无法打开存储路径选择弹窗,调试发现是报InvalidProgramException错误。可是打包后包里明明有System.Windows.Forms.dll 这个库,经过搜集资料...https://blog.csdn.net/humilezr/article/details/104615462        导入 csc.rsp 的之后,喜闻乐见又报错了:

        报错信息如下:

         ……csc.rsp: not parsed correctly: System.Windows.Forms.dll could not be found as a system library.

        If this was meant as a user reference please provide the relative path from project root (parent of the Assets folder) in the response file.

        等于是只能引用到Assets同级目录下的文件是吧,那不是等于没得搞?本来不就是这个dll有问题嘛……

4、解决思路2:更换dll文件

        后面看到了有个人跟我一样的问题:        unity使用 form.showDialog() 函数,打包后出现空指针错误 的解决方法_参宿_七的博客-CSDN博客需要实现一个unity打开文件/文件夹选择框,一开始使用:path = UnityEditor.EditorUtility.OpenFilePanel("Load Images of Directory", UnityEngine.Application.dataPath, extion);方法实现,但是这种方法只在编辑器里起作用,不能导出exe。于是使用:using System.Windows.Forms;OpenFileDialog dialog = new OpenFileDihttps://blog.csdn.net/Michaelia_hu/article/details/116015772        他提到一篇文章,说是需要修改引用的dll,我感觉这个思路挺靠谱的:

c # - the error occurs only after building openfiledialog in unityIn unity, I decided to use OpenFileDialog to specify the file. https://qiita.com/otochan/items/0f20fad94467bb2c2572 I imhttps://www.tutorialfor.com/questions-317730.htm

        之前是直接复制的 VS 自带的dll,后面进Unity不识别,报错。网上说的是要在Untiy安装目录下找 2.0.0 的那个。但是我之前用的时候就感觉有问题,因为 VS 自带的 dll 大概 2.7 mb,而Unity这个只有 730kb ,就很怪,但是在编辑器下又确实能运行。

        后面我换了一个目录下的:……MonoBleedingEdge\\lib\\mono\\unityjit-win32

        这个目录下面也有个 Winfrom 的dll,而且有2.7mb,我估计就是这个了。我把他导入到包里面,然后打包出来果然成功了:

        可见打包出来也能正常运行了。

        PS:使用Winfrom阶段,Unity 进程会暂停,等待窗口选择的返回,需要注意使用场景。

5、总结

  1. 找到Unity的安装目录,在此目录下:……\\Editor\\Data\\MonoBleedingEdge\\lib\\mono\\unityjit-win32 找到System.Windows.Forms.dll 这个文件。
  2. 将其放到Plugins下,Unity会自动添加引用。
  3. 直接代码使用打包即可。

6、注意事项

        我在编辑器下使用时,极易造成闪退(一般情况是,在调用API后当时没啥问题,但是一段时间后会突然闪退)!目前还不清楚具体原因,而且没有在打包后大量测试。目前建议是编辑器下测试时调用一下,测试通过之后不要再调用此代码。

Winform与WPF对话框(MessageBox, Dialog)之比较

原文:Winform与WPF对话框(MessageBox, Dialog)之比较

Winform:使用System.Windows.Forms命名空间中相应控件; WPF则调用Microsoft.Win32。

MessageBox:
// WinForm
        private void WFMessageBoxClicked(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.MessageBox.Show("Hello from Windows Forms!", "Hello World!");
        }

// WPF
        private void WPFMessageBoxClicked(object sender, RoutedEventArgs e)
        {
            System.Windows.MessageBox.Show("Hello from WPF!", "Hello world!");
        }

OpenFileDialog / SaveFileDialog:

// WinForm
        private void WinFormsDialogClicked(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog dialogOpenFile = new System.Windows.Forms.OpenFileDialog();
            dialogOpenFile.ShowDialog();

            //System.Windows.Forms.SaveFileDialog dialogSaveFile = new System.Windows.Forms.SaveFileDialog();
            //dialogSaveFile.ShowDialog();
        }

// WPF
        private void WPFDialogClicked(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dialogOpenFile = new Microsoft.Win32.OpenFileDialog();
            dialogOpenFile.ShowDialog();

            //Microsoft.Win32.SaveFileDialog dialogSaveFile = new Microsoft.Win32.SaveFileDialog();
            //dialogSaveFile.ShowDialog();
        }

以上是关于Unity使用 System.Windows.Forms 的问题的主要内容,如果未能解决你的问题,请参考以下文章

Control类的Invoke 和 BeginInvoke

[Unity优化] unity性能优化

在Unity中将Unity生成的代码与Objective-C混合使用?

Unity功能——Unity离线文档下载及使用

unity如何制作恶魔城小地图

Unity 框架QFramework v1.0 使用指南 架构篇:19. 心中有架构 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏