C#winform软件实现一次编译,跨平台windows和linux兼容运行,兼容Visual Studio原生界面Form表单开发

一、背景:

微软的.net core开发工具,目前来看,winform界面软件还没有打算要支持linux系统下运行的意思,要想让c#桌面软件在linux系统上运行,开发起来还比较麻烦。微软只让c#的控制台软件支持在linux运行。

二、解决方案:

我想到的一个方案是自定义封装软件的System.Windows.Forms组件,把支持windows和linux的界面框架GTK封装进System.Windows.Forms中!

三、组件封装

这个System.Windows.Forms是实现C#界面的关键组件,Form界面的所有控件都封装在这个组件里。在.net core环境里,这个组件在框架Microsoft.WindowsDesktop.App.WindownsForms下。当开发工程的输出模式是"windows应用程序"时,就会自动引用Microsoft.WindowsDesktop.App.WindownsForms,如果开发工程的输出模式是"控制台应用程序"时,工程不会引用Microsoft.WindowsDesktop.App.WindownsForms,也无法开桌面软件的界面。

为了兼容VS原生界面表单开发,我开发了这个组件GTKSystem.Windows.Forms,这个组件的控件类库命名空间和类名称沿用了原生System.Windows.Forms的类库名称,可以在原生开发的C#软件工程里,直接引用GTKSystem.Windows.Forms就能兼容运行。

四、技术开发

目前实现的控件:Form、Button、CheckBox、CheckedListBox、ComboBox、DataGridView、DateTimePicker、GroupBox、Label、LinkLabel、MaskedTextBox、MenuStrip、MonthCalendar、NumericUpDown、Panel、PictureBox、RadioButton、RichTextBox、SplitContainer、SplitterPanel、TabControl、TextBox、TreeView

以上控件都只实现了常用功能的属性和方法,事件主要实现了鼠标事件、验证事件、加载事件,还有很多平常不用的属性事件已经实现了接口,但是没有实现执行功能,主要是因为程序量太多,没有去做。对于有能力的开发人员,组件也是可以拿到相关的属性事件(如WidgetEvent)去实现需要的功能。

重写的类也很多,重点说一下这几个类:Bitmap、Image、System.ComponentModel.ComponentResourceManager、System.Resources.ResourceManager。这几个类是Form界面引用图像资源必需的。在控制台程序架构里,是没有Bitmap、Image类库的,而且ComponentResourceManager和ResourceManager都不能读取资源图像数据。我在GTKSystem.Windows.Forms里封装实现了Bitmap和Image类,实现了ComponentResourceManager和ResourceManager读取资源图像数据。

Bitmap和Image类除了常用属性外,新增属性Image.PixbufData存放图像数据,用于GTKSystem的使用。

ComponentResourceManager和ResourceManager主要是实现了GetObject方法,读取资源数据。

五、使用方法

修改.net core的windows应用程序工程属性,把输出类型改为"控制台应用程序",或者把windows窗体配置勾选去掉,配置变为<UseWindowsForms>false</UseWindowsForms>。

<PropertyGroup>

<OutputType>WinExe</OutputType>
<UseWindowsForms>false</UseWindowsForms>

</PropertyGroup>

1、新建System.Resources.ResourceManager类

在项目下新建System.Resources.ResourceManager类,继承GTKSystem.Resources.ResourceManager,用于覆盖原生System.Resources.ResourceManager类。

GTKSystem.Resources.ResourceManager实现了项目资源文件和图像文件读取。

如果项目里没有使用资源图像文件,可以不用新建此文件。

2、新建System.ComponentModel.ComponentResourceManager类

在项目下新建System.ComponentModel.ComponentResourceManager类,继承GTKSystem.ComponentModel.ComponentResourceManager,用于覆盖原生System.ComponentModel.ComponentResourceManager类。

GTKSystem.ComponentModel.ComponentResourceManager实现了项目资源文件和图像文件读取(调用GTKSystem.Resources.ResourceManager)。

如果项目里没有使用资源图像文件,可以不用新建此文件。

3、GTKWinFormsApp.csproj

配置UseWindowsForms为false,或者使用控制台应用程序

<UseWindowsForms>false</UseWindowsForms>

4、引用GTKSystem.Windows.Forms、System.Resources.Extensions

System.Resources.Extensions是空程序dll,VS加载Form界面时验证需要此dll.

5、GTKWinFormsApp\obj\Debug\netcoreapp3.1\GTKWinFormsApp.designer.runtimeconfig.json
GTKWinFormsApp\obj\Release\netcoreapp3.1\GTKWinFormsApp.designer.runtimeconfig.json

将name设置为Microsoft.WindowsDesktop.App,用于VS支持可视化Form表单,重新加载工程或重启VS

"runtimeOptions": {

"framework": {
"name": "Microsoft.WindowsDesktop.App"

},

六、使用效果:

VS开发界面:

运行效果:

最后:

此程序在统信系统(linux)上测试完美运行,实现一次编译,跨平台运行,显示界面样式与windows上运行的显示效果基本一样。

目前这个组件没有完全完成,但是主要功能和技术难点都已经解决,现公布出来给有需要的开发人员参考。

项目下载:https://files.cnblogs.com/files/easywebfactory/WinFormsAppDemo.zip?t=1698380585\&download=true

相关推荐
大大大大肉包26 分钟前
linux中挂载磁盘和卸载
linux·运维·服务器
三千道应用题2 小时前
C#模式匹配用法与总结
c#
深海潜水员2 小时前
【Unity】背包系统 + 物品管理窗口 (上)
开发语言·vscode·游戏·unity·c#·游戏引擎
伽蓝_游戏2 小时前
Unity UI的未来之路:从UGUI到UI Toolkit的架构演进与特性剖析(6)
游戏·ui·unity·架构·c#·游戏引擎·.net
kyranhan3 小时前
C#程序本地运行正常,通过网络下载报错:FileLoadException:“未能加载文件或程序集“xxx.dll”或它的某一个依赖项。
开发语言·c#·wpf
Yueeyuee_3 小时前
【C#学习Day14笔记】泛型、集合(数组列表Arraylist、列表list)与字典
笔记·学习·c#
AOwhisky3 小时前
云计算一阶段Ⅱ——3. Linux 计划任务管理
linux·chrome·云计算
wdfk_prog3 小时前
实战指南:如何将Git仓库中的特定文件夹及其历史完整迁移到另一个仓库
大数据·linux·运维·笔记·git·学习·elasticsearch
瑞士龙珠4 小时前
CentOS 7.4 → 7.9.2009 升级操作步骤(使用 Vault 仓库)
linux
highersister4 小时前
【RK3568源码编译准备工作】
linux