是否可以加入在编译时排除指定程序集

随便聊聊 · 64 次浏览
瞑空凌 创建于 5天13小时前

因生成程序集模块,在编写时经常多次编译生成,导致环境中存在多个同样命名空间,同样类型名的程序集
然后在C#模块或者自定义窗口调用时,就会因为类型重复导致冲突无法调用,但又不想每次重新运行都重启一下Quicker那么麻烦,因此是否可以加入排除指定程序集的功能
那么开发时就可以,在生成程序集后,保存生成程序集的路径,一旦判断生成程序集模块返回的路径和之前保存不一样,就排除之前保存的路径.

这样还有个好处,那就是做到使用的人更新动作后,让动作自己自动使用最新版本生成的程序集,而不会因为编译时程序集都被添加进来而导致冲突.


回复内容
瞑空凌 5天12小时前
#1

或者控制不自动加载,让手动在只编译时加载,不干涉现有程序域?👀

瞑空凌 5天11小时前
#2

或者只要是Quicker生成的都默认不添加到编译内,反正生成的程序集会返回路径,直接用路径手动明文指定使用这个

CL 5天10小时前
#3

程序集是根据代码哈希得到的文件名,所以如果代码变了,程序集也会变。 

程序集一经加载,是不能卸载的。

如果没有使用,程序集不会被加载。

瞑空凌 回复 CL 5天8小时前 :

C#模块以及自定义窗口,不是编译后才执行吗?🤔?难道是直接执行吗?我想的是如果是编译后执行,那么编译应该是需要指定程序集的,那么能否排除Quicker自己生成的程序集,加个输入框,让QUicker自己生成的程序集需要手动指定,这样编译后的程序集本身的环境就不会存在冲突类型.毕竟之前生成的程序集已经被排除编译环境了.
我想的就是C#模块或者自定义窗口,如果要使用生成程序集.返回的程序集,必须路径指定,这样因为不同编译的文件名唯一,那么代码中使用的类型也就是需要的那个程序集中的.
如果内部执行不是我想的这样,那就算了😂

瞑空凌 回复 CL 5天7小时前 :

说的有些繁琐,简化来说,就是我需要使用指定类型,但是环境存在多个命名空间一样,类型名一样,只有文件名不一样的,是否可以让模块只使用指定文件名程序集内的类型,  而不是我一使用这个类型,结果就是多个有同命名空间同类型的自生成程序集都被解析.
是否存在可以排除非指定程序集的方式

瞑空凌 回复 CL 5天7小时前 :

因为我写之前那个编译exe动作时,原本也是编译程序集,而编译程序集是需要指定使用的命名空间需要的程序集路径才能正确编译,然后我记得C#模块是有缓存程序集选项,所以C#模块应该也是生成了具体程序集文件...

我想的就是使用的命名空间需要的程序集路径时,手动指定一下,避免冲突,目前Quicker自己生成的程序集名称都是不可读名称,是否可以依据这个把自己生成的排除,只有手动指定的才会被添加进来.


就像表达式环境使用程序集一样,只有添加进来的才会被使用,而没有添加进来的,即使是在进程中被加载了的,也不能直接使用对应类型

瞑空凌 最后更新于 5天7小时前
CL 回复 瞑空凌 4天11小时前 :

这个有点超出我的理解能力了😂
所有代码肯定都是编译后执行的;
编译不需要指定程序集,有内存程序集;
所有程序集编译后会加载到进程里,似乎没有办法区分哪个程序集里的。不过我没有这方面的经验。

gpt是这么说的:

在 .NET 中,类型的完整标识不仅仅包括命名空间和类型名称,还包含所在的程序集(Assembly)信息。也就是说,即使多个 DLL 中有相同的命名空间和类型名称,只要它们来自不同的程序集,CLR 会把它们视为不同的类型。

如果同时加载到进程中,它们的区分主要有两种方法:

  1. 程序集限定名
    每个类型都有一个程序集限定名,格式大致为:

    命名空间.类型名称, 程序集名称, 版本, 文化, 公钥标记

    在反射或其他需要精确区分类型的场景中,可以使用这种方式来明确指定某个类型。

  2. 使用 extern alias
    当在一个项目中引用了多个包含相同命名空间和类型名称的 DLL 时,可以在项目中为其中一个或多个引用指定别名。然后在代码中使用 extern alias 来区分这些类型。例如:

    csharp
    // 为两个引用分别指定别名(在项目文件或引用属性中设置) // 假设引用的 DLL 分别为 AssemblyA.dll 和 AssemblyB.dll, // 分别被设置为别名:AliasA 和 AliasB extern alias AliasA; extern alias AliasB; using AType = AliasA::MyNamespace.MyType; using BType = AliasB::MyNamespace.MyType; class Program { static void Main() { AType objA = new AType(); BType objB = new BType(); // objA 和 objB 是来自不同 DLL 的同名类型,但它们被区分开了 } }

这样,通过使用程序集限定名或者 extern alias,开发者可以在同一个进程中同时加载和区分来自不同 DLL 中的相同命名空间和类型名称。

瞑空凌 回复 CL 4天11小时前 :

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
之前用这个编译程序集加密动作时,就是排除指定程序集,再添加指定的,因为Quicker引用mscorlib 程序集与加载的程序集冲突,导致使用这个编译失败,所以就复制程序集,用 Mono.Cecil库改一下版本号,把Quicker自己加载的mscorlib 程序集排除,使用自己改了版本的程序集,才编译成功,没有冲突,可以在动作内调用,所以后面问了你加密的可不可以发😂.虽然我后面去学另外的,不会再碰到会影响用户权限的代码了

编译肯定会需要程序集,个人理解应该是能中间插一手筛选的

瞑空凌 最后更新于 4天11小时前
瞑空凌 回复 CL 4天11小时前 :

我是想解决开发过程中因为改代码多次编译,以及动作更新也会出现的新旧代码不一致重新编译  导致的冲突,如果使用别名,如果使用别名,那代码就都要动态了,一个动就全动,使用起来也麻烦.所以我想是否控制在编译环境简化操作复杂度.

瞑空凌 回复 CL 4天11小时前 :

我看H-D-G大佬的demo动作Demo:自定义窗口——WinForm - by H-D-G - 动作信息 - Quicker,这里也有程序集添加,所以应该可以筛选截取,剔除不需要的


瞑空凌 回复 CL 4天11小时前 :

因此只需要把Quicker生成的哈希名称程序集排除,那么编译自然就不存在冲突,除了手动指定哈希名称程序集,不然不添加到编译过程.

回复主贴