csproj技巧,以及使用其他类库冲突,以及引入第三方UI方式

1、在项目中我们经常写

string? Message{get;set;}

明明是引用类型,它底下还是会出现波浪线,我们可以打开csproj
找到Nullable将它改为disable,或者删除,它默认是disable

<Nullable>disable</Nullable>

2、我们的WPF中可能会使用到Winform的类库,添加UseWindowsForms,一定要写在UseWPF下面

 <UseWPF>true</UseWPF>
 <UseWindowsForms>true</UseWindowsForms>

3、定制语言,防止其他语言注入

  <SatelliteResourceLanguages>en</SatelliteResourceLanguages>

在 C# 中,.csproj 文件是一个 XML 格式的文件,用于描述项目的结构和元数据,包括了代码文件、依赖项、编译选项、输出文件等。而 MSBuild 是一个通用的构建引擎,用于构建和部署 .NET 应用程序和其他类型的项目。MSBuild 可以通过执行指定的 .targets 和 .props 文件来执行构建操作,这些文件定义了一些属性和任务,用于控制构建过程中的行为和流程。

在 Visual Studio 中,.csproj 文件是由 MSBuild 来处理的。当您在 Visual Studio 中打开一个项目时,MSBuild 将会读取 .csproj 文件,并根据其中的内容生成一个项目对象模型(Project Object Model,POM)。POM 是一个内存中的表示项目的结构和元数据的对象,它包含了所有的配置信息、元素和属性。在 Visual Studio 中,您可以通过 Solution Explorer 或 Property Pages 窗口来查看和修改 POM。

在构建过程中,MSBuild 将会使用 POM 中的信息来执行构建操作。MSBuild 首先会执行 .props 文件中定义的属性,然后执行 .targets 文件中定义的任务,最后将生成的输出文件保存到指定的目录中。通过扩展 .props 和 .targets 文件,您可以自定义构建过程中的行为并添加自己的任务和属性。

总之,.csproj 文件和 MSBuild 引擎是密切相关的,.csproj 文件描述了项目的结构和元数据,而 MSBuild 引擎则负责执行构建操作并生成输出文件
但是程序运行后,我们会发现bin目录下的dll,json,exe,pdb文件杂乱无章
我们需要将dll分门别类,用到nulastudio.NetBeauty库
按照下面的方式写

<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<OutputType>WinExe</OutputType>
		<TargetFramework>net6.0-windows</TargetFramework>
		<Nullable>enable</Nullable>
		<UseWPF>true</UseWPF>
	</PropertyGroup>
	<PropertyGroup>
		<BeautySharedRuntimeMode>False</BeautySharedRuntimeMode>
		<!-- beauty into sub-directory, default is libs, quote with "" if contains space  -->
		<BeautyLibsDir Condition="$(BeautySharedRuntimeMode) == 'True'">../libraries</BeautyLibsDir>
		<BeautyLibsDir Condition="$(BeautySharedRuntimeMode) != 'True'">./libraries</BeautyLibsDir>
		<!-- dlls that you don't want to be moved or can not be moved -->
		<!-- <BeautyExcludes>dll1.dll;lib*;...</BeautyExcludes> -->
		<!-- dlls that end users never needed, so hide them -->
		<!-- <BeautyHiddens>hostfxr;hostpolicy;*.deps.json;*.runtimeconfig*.json</BeautyHiddens> -->
		<!-- set to True if you want to disable -->
		<DisableBeauty>False</DisableBeauty>
		<!-- set to False if you want to beauty on build -->
		<BeautyOnPublishOnly>False</BeautyOnPublishOnly>
		<!-- DO NOT TOUCH THIS OPTION -->
		<BeautyNoRuntimeInfo>False</BeautyNoRuntimeInfo>
		<!-- set to True if you want to allow 3rd debuggers(like dnSpy) debugs the app -->
		<BeautyEnableDebugging>False</BeautyEnableDebugging>
		<!-- the patch can reduce the file count -->
		<!-- set to False if you want to disable -->
		<!-- SCD Mode Feature Only -->
		<BeautyUsePatch>True</BeautyUsePatch>
		<!-- App Entry Dll = BeautyDir + BeautyAppHostDir + BeautyAppHostEntry -->
		<!-- see https://github.com/nulastudio/NetBeauty2#customize-apphost for more details -->
		<!-- relative path based on AppHostDir -->
		<!-- .NET Core Non Single-File Only -->
		<!-- <BeautyAppHostEntry>bin/MyApp.dll</BeautyAppHostEntry> -->
		<!-- relative path based on BeautyDir -->
		<!-- .NET Core Non Single-File Only -->
		<!-- <BeautyAppHostDir>..</BeautyAppHostDir> -->
		<!-- <BeautyAfterTasks></BeautyAfterTasks> -->
		<!-- valid values: Error|Detail|Info -->
		<BeautyLogLevel>Info</BeautyLogLevel>
		<!-- set to a repo mirror if you have troble in connecting github -->
		<!-- <BeautyGitCDN>https://gitee.com/liesauer/HostFXRPatcher</BeautyGitCDN> -->
		<!-- <BeautyGitTree>master</BeautyGitTree> -->
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="nulastudio.NetBeauty" Version="2.1.4.4" />
	</ItemGroup>

  <ItemGroup>
    <PackageReference Include="HandyControl" Version="3.5.1" />
    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
    <PackageReference Include="Prism.Wpf" Version="9.0.401-pre" />
	  <PackageReference Include="Prism.DryIoc" Version="9.0.401-pre" />
  </ItemGroup>
</Project>

注意,需要我们新建VS自带的,个别模板会和NetBeauty冲突,例如Prism
他虽然会编译成功,但是会启动失败,这个时候我们要删除App.xaml和App.xaml.cs
启动改为下面形式

/// <summary>
/// 使用Prism自带的模板启动失败,删除App.xaml和App.xaml.cs
/// 改为Main方法启动
/// </summary>
public class Program
{
    [STAThread]
    public static void Main() 
    {
        Application application = new Application();
        MainWindow win=new MainWindow();
        application.Run(win);
    }
}

说到这了,我顺便说下删除App后的几种启动方式

         [STAThread]
         static void Main() {
            Application app = new Application();  
            MainWindow win = new MainWindow(); 
            app.MainWindow = win;   
            win.Show(); // 显示窗体
            app.Run();  // 调用无参数的Run()方法
        }
         [STAThread]
         static void Main() {
            Application app = new Application();
            app.StartupUri = new Uri("MainWindow.xaml",UriKind.Relative); 
            app.Run();
        }

说到这里,再顺便说一句,我们如果把App.xaml删除了,那么我们使用第三方UI的时候怎么办呢
这是我使用Furiom框架写的WPF程序的启动,我是删除了App.xaml的,改用了

 public class Program
 {
     [STAThread]
     public static void Main(string[] args)
     {        
         // Serve.RunGeneric();
         Serve.RunNative(GetComponent());
         var app = new Application();       
         app.Startup += (sender, e) =>
         {
             //程序启动加载上一次关闭时SetData的数据状态           

             // 加载类库中的主题资源
             var themeResourceDictionary = ResourceExtension.LoadTheme();
             Application.Current.Resources.MergedDictionaries.Add(themeResourceDictionary);

             //WPF全局异常捕获
             ThreadExceptionHandler handler = new ThreadExceptionHandler();
             //UI线程抛出异常
             //  Application.Current.DispatcherUnhandledException += handler.Current_DispatcherUnhandledException;

             //非UI线程抛出异常
             //   AppDomain.CurrentDomain.UnhandledException += handler.CurrentDomain_UnhandledException;

             //Task线程抛出异常
             //   TaskScheduler.UnobservedTaskException += handler.TaskScheduler_UnobservedTaskException;

             //扫描全局的json文件
             //  JsonExtension.GetDefaultJsonLevel();

            
         };
         if (Native.CreateInstance<LoginView>().ShowDialog() == true)
         {
             //关闭登录窗体
             Native.CreateInstance<LoginView>().Close();
         }
     }

ResourceExtension是我自己定义的静态类
在这里我写两种方式供大家参考

 /// <summary>
 /// 加载资源字典的两种方式
 /// </summary>
 public static class ResourceExtension
 {
     public static ResourceDictionary Read()
     {
         var dictionaryXaml = @"
 <ResourceDictionary xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
                     xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
     <ResourceDictionary.MergedDictionaries>
         <ResourceDictionary Source=""pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"" />
         <ResourceDictionary Source=""pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml"" />
         <ResourceDictionary Source=""pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml"" />
         <ResourceDictionary Source=""pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Indigo.xaml"" />
     </ResourceDictionary.MergedDictionaries>
 </ResourceDictionary>";

         return (ResourceDictionary)System.Windows.Markup.XamlReader.Parse(dictionaryXaml);
     }


     public static ResourceDictionary LoadTheme()
     {
         // 加载资源字典
         var resourceDictionary = new ResourceDictionary();
         resourceDictionary.Source = new Uri("/System.MES.Theme;component/Properties/ApplicationResource.xaml", UriKind.RelativeOrAbsolute);

         return resourceDictionary;
     }
 }

本文作者:孤沉

本文链接:https://www.cnblogs.com/guchen33/p/18073891

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   孤沉  阅读(108)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开