C#「呼び出されたターゲットに異常が発生した」究極の解決策

7013 ワード

もんだいげんしょう


ダイナミックライブラリの内容を動的にロードするとき、次のエラーが発生しました.開発機に問題はなく、他の2台のテスト機に問題があります.次のエラーメッセージを出力します.
 :TargetInvocationException
 : 。
 :     System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
     System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
     System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
     System.Activator.CreateInstance(Type type, Boolean nonPublic)
     System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
     System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
     System.Reflection.Assembly.CreateInstance(String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
     System.Reflection.Assembly.CreateInstance(String typeName)
     CFW.WinForm.FrmMain.CreateForm(String className, String assemblyName
     CFW.WinForm.FrmMain.AddTabItem(S_Menu menu)
... ...

ソース:
        /// 
        ///  、 
        /// 
        /// 
        /// 
        /// 
        private Form CreateForm(string className,string assemblyName)
        {
            // Assembly 
            string path = Application.StartupPath + "\\" + assemblyName + ".dll";
            Assembly ass = Assembly.LoadFile(path);
           
            Form fm = (Form)Assembly.LoadFile(path).CreateInstance(className);
            
            Type fmType = fm.GetType();
            if (fmType.GetInterface("IFormBase") != null)
            {
                fmType.GetProperty("LoginUser").SetValue(fm, this.LoginUser);
                fmType.GetProperty("LoginDept").SetValue(fm, this.LoginDept);
            }
            fm.Tag = className;
            return fm;
        }

出错位置在“Form fm = (Form)Assembly.LoadFile(path).CreateInstance(className);”这一句。

の原因となる

通过度娘看了很多关于本问题的中文文档,有人提示必须加被加载dll的引用,有人提示cpu架构要保持一致(x86->x86,x64->x64),.Net Framework 框架要一致,甚至数据库是否正常连接。 还有人提示路径不对啥的。按照这些提示的思路去做,真的可能让人越来越产生绝望感。
后来在google上用英文“An exception occurred for the target of the call ”去查找答案,也没有找到直接的答案,但是有位高手的建议帮我找到了问题的真正原因。(参考这篇文章:
Exception has been thrown by the target of an invocation, when COM DLL’s are called by reflection technique in C#)
那就是,**TargetInvocationException掩盖了问题的真正原因,要查看Exception的InnerException。
** 我输出InnerException,内容如下:

 :FileNotFoundException
 : “Microsoft.ReportViewer.Common, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91” 。 。
 :     CFW.WinForm.FrmMain.AddTabItem(S_Menu menu)
... ...

これらの情報を見て、ロード対象のDLLに依存するDllファイルが不足していることが瞬時に分かった.

解決策


上の情報から問題の原因を見つけたら、解決策は簡単です.今回の解決策は、欠落したDLLファイルをロードパスと同じパスの下に置くことで正常です.もちろん、解決策は問題によって異なりますが、主にInnerExceptionのヒントを参考にします.