根据这篇文章,由于代码的JIT编译,.NET程序集不需要变基.文章指出:
"JIT编译的代码没有重定位问题,因为地址是在运行时根据代码放置在内存中的位置生成的.此外,MSIL很少受到基地址丢失的影响,因为MSIL引用是基于令牌的,而不是地址因此,当使用JIT编译器时,系统对基地址冲突具有弹性."
但是,我注意到VS2008为所有程序集分配了默认的0x0400000基址(项目属性>构建>高级),如果我listdlls /r为我的进程执行了一个操作,那么我的所有.NET程序集实际上都是默认的.
如果我自己分配地址,则不会进行变基.
我的问题是:在这种情况下,什么是重新定义的?为什么?
编辑:我应该补充一点,我不是在谈论NGen'ed集会.
包含托管代码和非托管代码混合的.NET程序集不能与其他程序集进行ILMerged.
如何验证给定的.NET程序集是包含纯托管代码,还是托管代码和非托管代码的混合?
我目前正在使用三段代码:
comobj.dll托管一个COM对象(比方说'MainInteract'),我想从Python中使用它.我已经可以在IronPython中完美地使用这个对象,但由于其他要求,我需要从常规Python中使用它.我相信这里最好的方法是使用win32com,但我根本无法取得任何进展.
首先,一些有效的IronPython代码:
import clr
import os
import sys
__dir__ = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, __dir__)
sys.path.append(r"C:\Path\To\comobj.dll") #This is where the com object dll actually is
clr.AddReferenceToFileAndPath(os.path.join(__dir__, r'comobj_1_1.dll')) #This is the .NET interop assembly that was created automatically via SharpDevelop's COM Inspector
from comobj_1_1 import clsMainInteract
o = clsMainInteract()
o.DoStuff(True)
Run Code Online (Sandbox Code Playgroud)
现在,我在常规Python中尝试的代码:
>>> import win32com.client
>>> win32com.client.Dispatch("{11111111-comobj_guid_i_got_from_com_inspector}")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python26\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File …Run Code Online (Sandbox Code Playgroud) 我的程序集中有很多入口点,我希望在运行此程序集中的任何其他代码之前,每个AppDomain执行一次初始化代码.最好的方法是什么?
我看到的一个解决方案是拥有一个带有静态构造函数的类,并继承我拥有的每个入口点.像这样的东西:
public class Initializer
{
static Initializer()
{
EnsureInitialized(); // Calls initialization code once and only once
}
}
public class EntryPointOne : Initializer, IEntryPoint
{
// Some code here
}
public class EntryPointTwo : Initializer, IEntryPoint
{
// Some code here
}
// etc.
Run Code Online (Sandbox Code Playgroud)
这让我可以避免在每个入口点编写样板静态构造函数,但是没有多继承,这并不总是可行的.你能想到其他更好的选择吗?
我正在使用以下代码:
AppDomain.CurrentDomain.AssemblyLoad += (sender, args) =>
{
var token = args.LoadedAssembly.GetName().GetPublicKeyToken();
if (!IsValidToken(token))
{
Process.GetCurrentProcess().Kill();
}
};
Run Code Online (Sandbox Code Playgroud)
凡IsValidToken()进行比较加载反对我作为字节数组应用硬编码授权的公钥标记列表组件的公钥标记.
这是防止代码注入攻击的良好安全措施吗?此外,鉴于我稍后将使用NetReactor混淆我的应用程序,这是否必要?我试图阻止任何"窥探"我的应用程序,不仅来自Snoop工具,而且来自任何外部不受欢迎的来源.
我有一些C#代码(让我们称之为"脚本")我在运行时编译.它使用我的主程序中的接口来访问其功能.编译完成后我就CompilerResults.CompiledAssembly可以了CreateInstance(Type).
一旦我完成了使用脚本,我想完全卸载.据我所知,如果我创建一个单独的应用程序域,我只能这样做:将 DLL加载到单独的AppDomain中
我有一些与我的实施有关的问题:
ReferencedAssemblies.Add(typeof(Interface).Assembly.Location)在编译之前正在做的事情.CompilerParameters GenerateInMemory=true,还是必须将其保存在某个地方?这里有一些争论,哪个更适合从其他项目引用我们的公共代码库:通过项目或汇编.我赞成引用该项目,特别是因为我们有自动化的单元测试,证明公共代码能够满足它的需要.
另一个阵营的想法是锁定那些项目,每月只发布一次或类似的东西.然后强制所有项目引用程序集.他们认为这将保护他们免于部署未经测试的代码.他们"太忙"无法编写自动化单元测试并将其项目配置为持续集成,我对此没有任何影响,所以请不要关注这方面.
这就是我能想到为什么项目参考是更好的解决方案的原因.我也在寻找其他意见.
优点:
缺点:
我在GAC中有"mycomp.myassembly.dll"但Load和LoadFrom会抛出找不到文件的异常,而LoadWithPartialName则返回null.我正在做以下事情:
AssemblyName name = new AssemblyName();
name.Name = "mycomp.myassembly.dll";
Assembly assembly = Assembly.Load(name);
Run Code Online (Sandbox Code Playgroud)
用于mycomp.myassembly.dll文件的FileNotFound失败,并且
Assembly assembly = Assembly.Load("mycomp.myassembly.dll");
Run Code Online (Sandbox Code Playgroud)
完全相同的消息失败了.
我仔细检查了汇编是否在GAC中(甚至再次使用gacutil/if)并且它在所有其他情况下都有效,我只是无法自己加载它.
我在这做错了什么?我错过了什么吗?
我可以将C#和C++/CLI源文件放在一个项目中,然后编译它们以获得单个.DLL程序集吗?
语境:
我的解决方案中有3个项目(C#,.NET 4.0):
Abc.Ui(Wpf项目)
Abc.Business是我的业务逻辑.它包含实体,经理,服务等.
Abc.Ui无法解析所有using Abc.Business;
错误日志显示:
错误名称空间'Abc'中不存在类型或命名空间名称'Business'(您是否缺少程序集引用?)c:\ Abc\Abc.Ui\ViewModels\ClientViewModel.cs
此外,当我手动输入using文件的顶部时,Intelli-sense会显示" Abc.Business.etc .. ".所以Intelli-sense走在引用中但是没有构建.
有任何想法吗 ?