我有问题......
我在运行时开发了用于创建动态DLL的代理类,并通过在我的项目中添加“references”在另一个项目中使用它。 我写道:VC 2010,.NET 4.0,C#。
public DynamicProxy(
string nameModule,
System.Reflection.Emit.AssemblyBuilderAccess accessModule,
string assemblyFileName = null,
IEnumerable<System.Reflection.Emit.CustomAttributeBuilder> customAttributes = null)
{
try
{
// module name
m_AssemblyFileName = assemblyFileName;
// try doing something
AppDomain domain = AppDomain.CurrentDomain;
// create assembly
m_MainBuilder = (customAttributes != null) ?
domain.DefineDynamicAssembly(
new System.Reflection.AssemblyName(nameModule) { Version = new Version("6.11.395.0610") },
accessModule,
customAttributes.ToArray()) :
domain.DefineDynamicAssembly(
new System.Reflection.AssemblyName(nameModule),
accessModule);
// create module
m_MainModule = (!string.IsNullOrEmpty(m_AssemblyFileName)) ?
m_MainBuilder.DefineDynamicModule(m_MainBuilder.GetName().Name, m_AssemblyFileName, true) :
m_MainBuilder.DefineDynamicModule(m_MainBuilder.GetName().Name, true);
// create properties storage
Properties = new Dictionary<string, PropertyTypeInfo>();
}
catch (Exception ex)
{
throw (new Exception(ex.Message));
}
}
public Type CreateInstance(string className, System.Reflection.TypeAttributes typeAccess)
{
Type result = null;
try
{
// create class
System.Reflection.Emit.TypeBuilder typeBuilder = m_MainModule.DefineType("System.Spyrytus.DynamicBuilder." + className, typeAccess);
// create constructor
System.Reflection.Emit.ConstructorBuilder cBuilder = typeBuilder.DefineConstructor(System.Reflection.MethodAttributes.Public, System.Reflection.CallingConventions.Standard, Type.EmptyTypes);
// create event
System.Reflection.Emit.FieldBuilder eventField =
typeBuilder.DefineField("PropertyChanged",
(!UsePropertyChangedEventHandler) ? typeof(PropertyChangedValueEventHandler) : typeof(System.ComponentModel.PropertyChangedEventHandler),
System.Reflection.FieldAttributes.Private);
// create event :D
System.Reflection.Emit.EventBuilder eventBuilder = typeBuilder.DefineEvent(
"PropertyChanged",
System.Reflection.EventAttributes.None,
typeof(System.ComponentModel.PropertyChangedEventHandler));
// add event handler
eventBuilder.SetAddOnMethod(CreateAddRemoveMethodsEvent(typeBuilder, eventField, true));
// remove handler
eventBuilder.SetRemoveOnMethod(CreateAddRemoveMethodsEvent(typeBuilder, eventField, false));
// handler
System.Reflection.Emit.MethodBuilder raise = CreateRaisePropertyChanged(typeBuilder, eventField);
eventBuilder.SetRaiseMethod(raise);
// create property
List<System.Reflection.Emit.PropertyBuilder> fields = CreatePropery(ref typeBuilder, cBuilder.GetILGenerator(), raise);
System.Reflection.Emit.MethodBuilder toStrMethod = typeBuilder.DefineMethod(
"ToString",
System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.ReuseSlot,
typeof(string),
Type.EmptyTypes);
typeBuilder.DefineMethodOverride(toStrMethod, typeof(object).GetMethod("ToString"));
System.Reflection.Emit.ILGenerator toStr = toStrMethod.GetILGenerator();
// create StringBuilder in string
System.Reflection.Emit.LocalBuilder retValue = toStr.DeclareLocal(typeof(StringBuilder));
toStr.Emit(System.Reflection.Emit.OpCodes.Newobj, retValue.LocalType.GetConstructor(Type.EmptyTypes));
toStr.Emit(System.Reflection.Emit.OpCodes.Stloc_S, retValue);
System.Reflection.Emit.Label exception = toStr.BeginExceptionBlock();
// read all property
foreach (System.Reflection.Emit.PropertyBuilder piItem in fields)
{
// local variable
System.Reflection.Emit.LocalBuilder local = toStr.DeclareLocal(piItem.PropertyType);
// read value
toStr.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
toStr.Emit(System.Reflection.Emit.OpCodes.Call, piItem.GetGetMethod());
toStr.Emit(System.Reflection.Emit.OpCodes.Stloc_S, local);
// create Format
toStr.Emit(System.Reflection.Emit.OpCodes.Ldloc_S, retValue);
toStr.Emit(System.Reflection.Emit.OpCodes.Ldstr, piItem.Name + ": {0}\r\n");
toStr.Emit(System.Reflection.Emit.OpCodes.Ldloc_S, local);
toStr.Emit(System.Reflection.Emit.OpCodes.Box, piItem.PropertyType);
toStr.Emit(System.Reflection.Emit.OpCodes.Callvirt, retValue.LocalType.GetMethod("AppendFormat", new Type[] { typeof(string), piItem.PropertyType }));
toStr.Emit(System.Reflection.Emit.OpCodes.Pop);
}
toStr.BeginCatchBlock(typeof(Exception));
toStr.EndExceptionBlock();
// exit from method
toStr.Emit(System.Reflection.Emit.OpCodes.Ldloc_S, retValue);
toStr.Emit(System.Reflection.Emit.OpCodes.Callvirt, retValue.LocalType.GetMethod("ToString", Type.EmptyTypes));
toStr.Emit(System.Reflection.Emit.OpCodes.Ret);
// create type
result = typeBuilder.CreateType();
}
catch (Exception ex)
{
throw (new Exception(ex.Message));
}
return result;
}
创建动态对象:
using (Spyrytus.Windows.MSSQL.DynamicProxy proxy = new Spyrytus.Windows.MSSQL.DynamicProxy("module", System.Reflection.Emit.AssemblyBuilderAccess.Save, "object.dll", attrs))
{
proxy.CreateInstance("Foo", System.Reflection.TypeAttributes.Public);
proxy.Save();
}
通过右键单击鼠标在参考中添加此DLL,并尝试使用它:
System.Spyrytus.DynamicBuilder.Foo t = new System.Spyrytus.DynamicBuilder.Foo()
错误:
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll Additional information: Could not load file or assembly 'module, Version=6.11.395.610, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Could not found special file.
这是什么意思?
问候:尤金。
答案 0 :(得分:0)
使用Dependency Walker实用程序http://www.dependencywalker.com
调查您的EXE非常值得它会告诉您哪些模块实际导入EXE(因此它们必须可用于运行您的EXE)。你能说明Dependency Walker找到哪些导入?