在不同电脑上运行C#程序时出现System.IO.FileLoadException错误

3
我目前正在开发一个C# WPF项目,该项目使用MySQL.Data和System.Data.Sqlite dll以及其他一些dll。
该项目是一个.Net 4项目,在我的开发机器上运行没有问题。我创建了一个MSI安装程序包,当我添加可执行文件时,Visual Studio会解决依赖关系并添加所需的DLL到EXE中。
当我在我的开发机器上运行安装程序时,一切都正常。然而,当我将安装程序复制到安装了.Net Framework 3.5和.Net Framework 4的空白虚拟机上时,安装程序显示一切都已成功安装,当我查看程序文件夹时,所有的DLL也都在那里,但当我尝试运行软件时,软件无法加载,并在事件查看器中显示了.Net Runtime错误。
错误信息如下:
应用程序:MySQLBackup.exe 框架版本:v4.0.30319 描述:由于未处理的异常,该进程已终止。 异常信息:System.IO.FileLoadException 堆栈:at MySQLBackup.App.Application_Startup(System.Object, System.Windows.StartupEventArgs) at System.Windows.Application.OnStartup(System.Windows.StartupEventArgs) at System.Windows.Application.<.ctor>b__1(System.Object) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object) at System.Threading.ExecutionContext.runTryCode(System.Object) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object) at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) at System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr) at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef) at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame) at System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame) at System.Windows.Threading.Dispatcher.Run() at System.Windows.Application.RunDispatcher(System.Object) at System.Windows.Application.RunInternal(System.Windows.Window) at System.Windows.Application.Run(System.Windows.Window) at System.Windows.Application.Run() at MySQLBackup.App.Main()
错误信息并不能帮助我找出问题所在,因此我在应用程序启动事件中添加了try catch语句,但是异常从未被捕获。我还在InitialiseComponent()方法周围添加了try catch,这个方法在第一个应该加载的对话框窗口上执行,但是再次没有捕获到异常,因此我无法看到导致错误的原因。
如何找出问题并解决它?
3个回答

4
How can I figure out what this problem is and fix it.

使用Visual Studio远程调试器进行远程调试。 本教程可以帮助您了解如何使用它。
一旦您熟悉了VS远程调试,您将始终使用这个强大的工具在潜在客户环境中进行测试。
至于您特定的问题,您有一些代码在Application.Startup事件处理程序中尝试加载某个文件并失败。如果您无法自己找到问题源,请在您的App.xaml中发布代码,以便我们分析。

谢谢你的帮助。我已经按照@radik提到的使用了远程调试和fuslogvw,但出现了更奇怪的问题。它说找不到System.Data.Sqlite.dll,即使文件在...bin/myapp/system.data.sqlite.dll中存在。更奇怪的是,在开发机器上,即使程序正常加载且没有抛出任何异常,这个错误也会在fuslogvw中显示。 - Boardy
嗨,我发现问题了。这是由于我创建的用于安装程序的MSI文件没有包含myapp.exe.config文件。一旦将其包括在MSI中,它就运行得很好。感谢您和@Radik的帮助,你们两个的答案都有所帮助。再次感谢! - Boardy
很高兴听到你已经全部搞定了 :) - Maxim V. Pavlov

3

这可能比尝试让远程调试工作更好的第一步。但是,如果没有安装VS,则无法正常工作,除非您复制正确的文件,请参见在未安装Visual Studio的计算机上使用FUSLOGVW.EXE - Conrad Frix

1

根据堆栈跟踪,问题发生在被OnStartup调用的Application_Startup中。因此,您应该检查是否在可能生成这些异常的代码中实现/覆盖或连接到了这些事件。由于多个方法可以订阅事件处理程序,所以无法保证问题在您的代码中。

您可以创建一些日志检查点来帮助缩小错误位置,并记录错误上下文中的值。

您还可以使用远程调试来尝试缩小错误位置。

还有一些未处理的异常事件处理程序,您可以搜索并学习如何实现它们,以便在错误发生时执行日志记录,但通常在那时获取更多信息已经太晚了,除了优雅地关闭,这可能是最后的选择。

您还可以使用SysInternals工具(例如http://technet.microsoft.com/en-us/sysinternals/bb896645)来确定程序正在尝试访问哪些文件,并过滤掉失败的文件。

你可以确定它最后尝试访问的文件是什么,甚至可能在操作系统级别上看到错误。我发现这个工具在处理奇怪的文件访问问题时非常有价值。不过需要一些时间来弄清楚。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接