cad.net 从.net framework移植到.net standard
说明
首先要说明的是.net standard是为了生成不同net版本的dll而存在的.
若你想要生成不同版本的exe,需要.net5的技术
移植需求
采用 .net standard 类库和 nuget 的方式的好处是:
- .net的发展的趋势就是干掉 frameworks 类型,只保留 standard(core) 类型。frameworks在4.8版本之后就不在升级了,以后都会统一到.net 5。
因此现在采用standard类型是一个正确的选择。 - 经过测试,cad是支持standard类型的类库加载和运行的,因此建议发现不可修复的bug之前,针对cad的二次开发也采用standard类型的类库。
- 采用nuget管理引用是可以不用管本地是否有要引用的dll文件,同时nuget安装的类库还会自动升级,方便采用更新的类库。
以上摘录自: https://gitee.com/inspirefunction/ifoxcad
因此,我将工程移植到 .net standard....
而很幸福的是,只需要学习写.csporj文件就可以了,基本不用怎么改代码,
但是变量同名跨域的操作,还是需要改一下代码,
.net framework是不穿透的:
var tr = docxxxxxxx;
db.Action( tr => 这个tr是新的.
而.net standard两个tr会提示错误,要求你必须改.
WinForm的资源文件要重新关联一下,因为 standard 要有一个单独的 Resources 资源文件夹存放.
更多信息可能需要大家自己实践.
加载
cad08.09.10.11.12
会同时占用net3.5版本,所以我并没有制作这些nuget包,
因为我的操作是cad加载的时候用同net版本号最低的那个就行了,也就是这里09.10.11.12
统统加载08
的,
如果在同net版本的新cad有新函数,那么只需要反射调用就好了.
毕竟net standard
也不能实现多个相同net版本工程,
例如cad08.09.10.11.12
同为net35,这样编译后会同时输出在一个net35文件夹,导致冲突.
我下面保留了一个cad10的操作给大家尝试一下.
快速移植
1: 复制粘贴我的.csproj文件到你工程的.csproj文件
2: 删除项目Properties文件夹中冲突的部分,一般来说我是全删的...如果你有做其他工作的话,请保证备份.
我完整的.csproj文件:
我的自制的dll包已经上传到了微软的服务器,如果缺少的部分是感叹号,去删掉对应的位置就好了.
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<!--永远支持最新语法 preview,默认是latestMajor-->
<LangVersion>preview</LangVersion>
<!--版本号迭代-->
<AssemblyVersion>1.0.0.*</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<Deterministic>False</Deterministic>
<TargetFrameworks>NET35;NET40;NET45;NET46;NET47;NET48</TargetFrameworks>
<!-- 支持wpf -->
<UseWpf>true</UseWpf>
<!-- 支持winform -->
<UseWindowsForms>true</UseWindowsForms>
<!-- 以下是默认引用相关依赖的属性 WPF -->
<ExtrasEnableWpfProjectSetup>true</ExtrasEnableWpfProjectSetup>
<!-- 以下是默认引用相关依赖的属性 WindowsForms -->
<ExtrasEnableWinFormsProjectSetup>true</ExtrasEnableWinFormsProjectSetup>
<!--输出路径-->
<OutputPath></OutputPath>
</PropertyGroup>
<!--DEBUG设置-->
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net35|AnyCPU'">
<DefineConstants>DEBUG;AC2008</DefineConstants>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|AC2010|AnyCPU'">
<DefineConstants>DEBUG;AC2010</DefineConstants>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net40|AnyCPU'">
<DefineConstants>DEBUG;AC2013</DefineConstants>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net45|AnyCPU'">
<DefineConstants>DEBUG;AC2015</DefineConstants>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net46|AnyCPU'">
<DefineConstants>DEBUG;AC2017</DefineConstants>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net47|AnyCPU'">
<DefineConstants>DEBUG;AC2019</DefineConstants>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net48|AnyCPU'">
<DefineConstants>DEBUG;AC2021</DefineConstants>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<!--Release设置-->
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|NET35|AnyCPU'">
<DefineConstants>TRACE;AC2008</DefineConstants>
<PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|AC2010|AnyCPU'">
<DefineConstants>TRACE;AC2010</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net40|AnyCPU'">
<DefineConstants>TRACE;AC2013</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net45|AnyCPU'">
<DefineConstants>TRACE;AC2015</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net46|AnyCPU'">
<DefineConstants>TRACE;AC2017</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net47|AnyCPU'">
<DefineConstants>TRACE;AC2019</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net48|AnyCPU'">
<DefineConstants>TRACE;AC2021</DefineConstants>
</PropertyGroup>
<!--MSBuild条件 版本号运算 https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild-conditions?view=vs-2019 -->
<!--WPF需要的dll,System.Xaml在net35没有-->
<ItemGroup Condition="'$(TargetFramework)' != 'net35'">
<Reference Include="System.Xaml" />
<PackageReference Include="CommonServiceLocator" Version="2.0.2" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net35'">
<!--ExcludeAssets 因为Acad2008不可以复制dll到目标,否则会无法使用命令-->
<PackageReference Include="JJBox.Acad2008" Version="1.0.0" ExcludeAssets="runtime" />
<PackageReference Include="CommonServiceLocator" Version="1.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
<PackageReference Include="JJBox.Acad2013" Version="1.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<PackageReference Include="JJBox.Acad2015" Version="1.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net46'">
<PackageReference Include="JJBox.Acad2017" Version="2.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net47'">
<PackageReference Include="JJBox.Acad2019" Version="2.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<PackageReference Include="JJBox.Acad2021" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<!--WPF的包 WPF的程序集引用-->
<PackageReference Include="MvvmLightLibs" Version="5.4.1.1" />
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WindowsBase" />
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="iTextSharp" Version="5.5.13.1" />
<PackageReference Include="log4net" Version="2.0.12" />
<PackageReference Include="Microsoft.QualityTools.Testing.Fakes" Version="16.7.4-beta.20330.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="QRCoder" Version="1.4.1" />
<Reference Include="System.Management" />
<Reference Include="System.Runtime.Remoting" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="PresentationFramework" />
<PackageReference Include="SQLite" />
</ItemGroup>
<ItemGroup>
<!--排除引用的包文件目录-->
<Compile Remove="FakesAssemblies\**" />
<EmbeddedResource Remove="FakesAssemblies\**" />
<None Remove="FakesAssemblies\**" />
<Page Remove="FakesAssemblies\**" />
</ItemGroup>
</Project>
然后记得安装net目标包.
实现过程的一些说明
界面支持
写.csproj文件,支持WinFrom和WPF:
我在移植的时候发现了一个很重要的问题 .net framework 环境下面的 WPF和winform 窗体设计器 InitializeComponent(); 这个语句会不断发生无法检索的问题,
因为这文件是vs自己生成的,不可以通过修改路径的方法将它呈现给编译器,在实现了很多个不同的方法之后,发现了,有的只支持WinFrom有的只支持WPF.
而 .net standard 上面也会遇到这个问题,这是移植要解决的第一个问题.
.csproj 文件的第一句:
如果你是个萌新,那么直接新建的 .net standard 工程,那么它是只支持 WinForm 的
<Project Sdk="Microsoft.NET.Sdk">
如果你找到了这一句,替代进去,那么它只支持了..WPF....
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
如果你看到了我的博文,那么这一句,终于同时支持了这两个鬼东西了...原因是net core3.1的推出...
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
版本和引用处理:
WPF的MarkupExtension接口引用问题,System.Xaml.dll的引用问题:
WPF 存在一个版本差,这个版本差分别是低版本的 net3.5 和 高版本的 net4.0,
而WPF的 MarkupExtension 接口在 net3.5 和 net4.0 之间有差异,这个差异需要在 net4.0(或以上) 引用一个 System.Xaml.dll 来解决.
在.csporj文件这里写上引用:
但是因为要判断 net 的版本,所以需要写在这里:
图文教程:
(以下是小贱贱总结的...我会加一点注释上去,方便大家理解).
双击这个位置,就可以编辑.csproj文件哟~
粘贴我本篇文章的.csproj
要注意的事项
注明:
找nuget包之后点安装,实际上来说是一个十分不明智的操作,因为这样会安装在所有的net版本上面,
也就是它会自动写在.csproj最下面的公共部分,而当你需要写在特定位置的时候可以利用nuget包名字写在.csproj的net版本.
别名方便区分cad的版本的话,可以按如下的方式进行
调试
调试的时候如果没有命中断点,请修改这个位置.
9.0新语法
20210224支持c#9.0语法,在.csproj文件上面加上:
<PropertyGroup>
<LangVersion>9.0</LangVersion>
<PropertyGroup>
但是只支持9.0那到10.0又要改,所以最好是用以下的,支持预览版:
<PropertyGroup>
<!--永远支持最新语法 preview,默认是latestMajor-->
<LangVersion>preview</LangVersion>
</PropertyGroup>
这些我已经修改在了上面的完整文件上了,若看到可以忽略.
记得更新vs,才能使用新语法,新语法参考:
https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-9
https://devblogs.microsoft.com/dotnet/c-9-0-on-the-record
(完)