2019-11-29-Roslyn-如何在-Target-引用-xaml-防止文件没有编译
title | author | date | CreateTime | categories |
---|---|---|---|---|
Roslyn 如何在 Target 引用 xaml 防止文件没有编译
|
lindexi
|
2019-11-29 08:58:53 +0800
|
2018-09-04 08:54:27 +0800
|
Roslyn MSBuild 编译器 xaml 打包
|
在使用新的项目格式,可以使用 Target 添加项目,但是有一些项目需要在合适的时候添加,如果添加早了,那么会让用户看到这些文件,如果添加的时间是在引用编译之后,那么文件将无法进行编译。
本文是更多请看手把手教你写 Roslyn 修改编译 的一个文章,在开始本文之前,假设大家已经了解 Roslyn 相关。
本文主要是我自己探索 VisualStudio 编译的过程,所以有一点乱,主要的过程就是遇到了将 xaml 写在了 Traget 里,编译的时候因为找不到 xaml 编译,所以无法编译通过。
于是我就不断在早一个 Target 在这个 Target 之前添加编译 xaml 就可以让 VisualStudio 编译通过
先来说结论
通过 BeforeTargets="GenerateBindingRedirects"
里添加 xaml 文件就可以让 VisualStudio 编译的时候编译添加 xaml 编译。
但一个准确的时机是 BeforeTargets="MarkupCompilePass1"
里面添加 xaml 文件,详细请看 WPF 程序的编译过程
本文以下的内容只是记录我做过的测试
也就是通过下面代码添加的 MainPage.xaml 可以被编译
<Target Name="MoqakermirLaqouLurter" BeforeTargets="GenerateBindingRedirects">
<ItemGroup>
<Page Include="MainWindow.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
</ItemGroup>
</Target>
下面是记录过程,如果只是想要知道结论,那么下面的文章就不需要看了。
首先来创建一个空白的 WPF 程序,使用从以前的项目格式迁移到 VS2017 新项目格式的方法修改 WPF 程序为新项目格式,然后开始来修改 xaml 的加入时间。
一个空白的 WPF 程序会包含这些内容
compile 编译的文件
App.xaml.cs
MainWindow.xaml.cs
Program.cs
Properties\AssemblyInfo.cs
Properties\Resources.Designer.cs
Properties\Settings.Designer.cs
C:\Users\lindexi\AppData\Local\Temp\.NETFramework,Version=v4.5.AssemblyAttributes.cs
obj\Debug\net45\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
obj\Debug\net45\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
obj\Debug\net45\TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
D:\lindexi\github\BemateRaimarhas\obj\Debug\net45\App.g.cs
D:\lindexi\github\BemateRaimarhas\obj\Debug\net45\MainWindow.g.cs
D:\lindexi\github\BemateRaimarhas\obj\Debug\net45\BemateRaimarhas_Content.g.cs
obj\Debug\net45\BemateRaimarhas.AssemblyInfo.cs
EmbeddedResource 嵌入资源
Properties\Resources.resx
None 无编译文件
App.config
App.xaml
MainWindow.xaml
Properties\Settings.settings
Page 页面文件
App.xaml
MainWindow.xaml
默认没有包含内容和资源文件
注意,默认空白的项目在页面文件和无编译文件存在 MainWindow.xaml
等文件。这些文件是重复的,可以使用下面代码去掉无编译的 MainWindow.xaml
文件
<None Remove="**\*.xaml"></None>
如果尝试去掉下面的代码,也就是所有的 xaml 文件都没有添加编译
<Page Include="**\*.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
这时会出现编译不通过
MainWindow.xaml.cs(25,13): Error CS0103: 当前上下文中不存在名称“InitializeComponent”
Program.cs(15,17): Error CS1061: “App”未包含“InitializeComponent”的定义,并且找不到可接受第一个“App”类型参数的可访问扩展方法“InitializeComponent”(是否缺少 using 指令或程序集引用?)
那么现在尝试使用 Target 来添加这两个文件,为什么需要使用 Target 而不是直接写 ItemGroup 是因为我需要在用户的 VisualStudio 看不到这些文件。很多时候可以使用 Visible="False"
隐藏文件,但是如果这个文件刚好放在一个文件夹里面,那么这个文件夹将会被用户看到。也就是用户可以删除这个文件夹,一旦这个文件夹删了,那么文件夹里面的文件也就是无法编译通过,这时小伙伴就会过来打我
<Page Include="App.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
<Page Include="MainWindow.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
一开始我就知道将文件放在 Target 里可以设置让用户看不到引用的文件,写一个 Target 需要包含一个 Name 所以我就写出下面代码
<Target Name="MoqakermirLaqouLurter">
<ItemGroup>
<Page Include="App.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
<Page Include="MainWindow.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
</ItemGroup>
</Target>
当然,上面的 Page 是不会被添加的,原因是 MSBuild 不知道什么时候运行上面的代码。为了让 MSBuild 运行上面的 Target 我就需要给 BeforeTargets
在一开始我就尝试用的比较多的 CoreCompile 请看代码
<Target Name="MoqakermirLaqouLurter" BeforeTargets="CoreCompile">
<ItemGroup>
<Page Include="App.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
<Page Include="MainWindow.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
</ItemGroup>
</Target>
上面的代码会在 BeforeTargets="CoreCompile"
运行,但是还是无法编译通过
于是就找到了 XamlPreCompile
替换 CoreCompile 请看下面
<Target Name="MoqakermirLaqouLurter" BeforeTargets="XamlPreCompile">
<ItemGroup>
<Page Include="App.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
<Page Include="MainWindow.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
</ItemGroup>
</Target>
但是在 MSBuild 是没有运行 XamlPreCompile 的,所以上面的代码没有运行,也是编译不通过
尝试使用 GenerateBindingRedirects
替换 XamlPreCompile
请看下面
<Target Name="MoqakermirLaqouLurter" BeforeTargets="GenerateBindingRedirects">
<ItemGroup>
<Page Include="App.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
<Page Include="MainWindow.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
</ItemGroup>
</Target>
现在就可以编译通过了,而且在用户的代码也看不到 xaml 文件,我就是通过这个方法开发。也就是经过了 CoreCompil XamlPreCompile 找到了 GenerateBindingRedirects 可以解决文件引用。
那么相比写在 ItemGroup 而不经过 Target 有什么好处?
如果这时将会 MainWindow.xaml
放在了一个文件夹 View 只要有引用这个文件,无论有没设置是否隐藏,开发者都可以看到 View 文件夹,而且可以删除这个文件夹,如果删除了这个文件夹,那么就无法编译
如使用下面的代码,即使设置 MainWindow.xaml 不可见,但是用户还是可以在 VisualStudio 看到一个空文件夹
<ItemGroup>
<Page Include="App.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
<Page Include="View\MainWindow.xaml" SubType="Designer" Generator="MSBuild:Compile" Visible="False"></Page>
</ItemGroup>
但是如果放在 Target 里就无法看到引用的文件夹,也就无法删除文件夹,通过这个方法可以让我使用源代码打包
如使用下面的代码,即使没有设置 MainWindow
不可见,用户也是看不见这个文件
<Target Name="MoqakermirLaqouLurter" BeforeTargets="GenerateBindingRedirects">
<ItemGroup>
<Page Include="App.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
<Page Include="View\MainWindow.xaml" SubType="Designer" Generator="MSBuild:Compile"></Page>
</ItemGroup>
</Target>
源代码打包项目是为了解决很小的代码,都需要做出一个 nuget 包,这个 nuget 包是 dll 也就是软件会引用太多的 dll ,大家都知道如果引用的 dll 多了,软件启动速度也就是变慢了。所以我就使用打包 nuget 包但是引用的是源代码的方式,这样开发者在安装 nuget 之后可以快速调试安装的库的源代码。
2019-11-29-Roslyn-如何在-Target-引用-xaml-防止文件没有编译的更多相关文章
- 2019.11.29 Mysql的数据操作
为名为name的表增加数据(插入所有字段) insert into name values(1,‘张三’,‘男’,20); 为名为name的表增加数据(插入部分字段) insert into name ...
- 2019.11.29 SAP SMTP郵件服務器配置 發送端 QQ郵箱
今天群裏的小夥伴問了如何配置郵件的問題,隨自己在sap裏面配置了一個 1. RZ10配置參數 a) 参数配置前,先导入激活版本 执行完毕后返回 b) 输入参数文件DEFAU ...
- pycharm+anaconda在Mac上的配置方法 2019.11.29
内心os: 听人说,写blog是加分项,那他就不是浪费时间的事儿了呗 毕竟自己菜还是留下来东西来自己欣赏吧 Mac小电脑上进行python数据开发环境的配置 首先下载Anaconda,一个超好用的数据 ...
- Supervision meeting notes 2019/11/29
topic 分支: 1. subgraph/subsequence mining Wang Jin, routine behavior/ motif. Philippe Fournier Viger ...
- EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)
传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f( ...
- C++11新特性之右值引用(&&)、移动语义(move)、完美转换(forward)
1. 右值引用 个人认为右值引用的目的主要是为了是减少内存拷贝,优化性能. 比如下面的代码: String Fun() { String str = "hello world"; ...
- 黑盒测试实践--Day5 11.29
黑盒测试实践--Day5 11.29 今天完成任务情况: 分析系统需求,完成场景用例设计 小组负责测试的同学学习安装自动测试工具--QTP,并在线学习操作 小黄 今天的任务是完成场景测试用例的设计.在 ...
- Alpha冲刺(6/10)——2019.4.29
所属课程 软件工程1916|W(福州大学) 作业要求 Alpha冲刺(6/10)--2019.4.29 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪 ...
- [New!!!]欢迎大佬光临本蒟蒻的博客(2019.11.27更新)
更新于2019.12.22 本蒟蒻在博客园安家啦!!! 本蒟蒻的博客园主页 为更好管理博客,本蒟蒻从今天开始,正式转入博客园. 因为一些原因,我的CSDN博客将彻底不会使用!!!(带来不便,敬请谅解) ...
- [转][c++11]我理解的右值引用、移动语义和完美转发
c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...
随机推荐
- Python遍历列表删除多个元素或者重复元素
在遍历list的时候,删除符合条件的数据,结果不符合预期 num_list = [1, 2, 2, 2, 3] print(num_list) for item in num_list: if i ...
- linux 实现U盘自动挂载
某些场景下,服务器可能没有必要的键盘等输入设备.屏幕等输出设备.此时需要在没有人为干预的情况下实现当插入U盘或者硬盘后自动挂载,并执行某些脚本动作.以下是我的实践过程. 必要组件 udev,udisk ...
- 怎样查看explorer里运行的DLL文件
怎样查看explorer里运行的DLL文件 tasklist /m /fi "imagename eq explorer.exe">a.txt 列出explorer用的所有模 ...
- web安全之如何防止CSRF跨站请求伪造(转载)
https://www.cnblogs.com/blibli/p/7658168.html CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click ...
- Android内存Activity泄露:Handler与Threads
Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向,则该对象会在被 ...
- 使用docker 部署python 项目
使用python 开发了一个restfu api程序,使用docker镜像部署.主要有如下步骤,简单记录以供以后参考. 1. 创建DockerFile文件 创建一个DockerFile文件,文件名为D ...
- 描述一下 Intent 和 IntentFilter?
Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内 ...
- CICD - 持续集成与持续交付
持续集成与持续交付是软件开发和交付中的实践.我们项目中一直在践行持续集成(CI:Continuous Integration):持续交付(CD:Continuous Delivery)未能达到理想状态 ...
- 破解root
启动grub按E,进入编辑,ro 改为 rw init=/sysroot/bin/sh然后Ctrl+X进入单用户# chroot /sysroot# passwd root# touch /.auto ...
- django 通过模型类操作数据表(基础增删改查)
进入项目shell的命令: python manage.py shell 以下为在相互shell终端中演示的例子: 首先导入模型类:(from 应用名.models import 类名) from b ...