FileNotFoundException异常的ApplicationSettingsBase [英] FileNotFoundException in ApplicationSettingsBase

查看:313
本文介绍了FileNotFoundException异常的ApplicationSettingsBase的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在调试应用程序时的异常休息在Visual Studio中启用我总是碰到下面的错误。这实在是烦我,因为我们与例外破工作。有趣的是,当我继续(在StringCollection加载),它仍然有效。

When debugging an application I always get the following error when break on exception is enabled in Visual Studio. This is really bugging me, since we work with break on exception. The funny thing is, that it still works when I continue (the StringCollection is loaded).

该消息是:

无法加载文件或程序集System.XmlSerializers,版本= 4.0.0.0,文化=中性公钥= b77a5c561934e089或它的一个依赖。该系统找不到指定的文件。

Could not load file or assembly 'System.XmlSerializers, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.

下面是code,是造成异常(设计器生成)

Here is the code that is causing the exception (designer generated)

[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Collections.Specialized.StringCollection Mru {
        get {
            return ((global::System.Collections.Specialized.StringCollection)(this["Mru"]));
        }
        set {
            this["Mru"] = value;
        }
    }

我试图创建一个空的测试应用程序,显示错误,但并没有出现异常。我们的项目是巨大的​​,因此很难找到原因。也许有人对这个网站有一个线索如何解决这个问题。

I tried to create an empty test application that shows the error, but the exception didn't occur. Our project is huge so it tough to find the cause. Maybe someone on this site has a clue how to solve this.

推荐答案

为什么抛出此异常只是一个解释。您可以瑞普此示例Windows窗体应用程序除外。通过添加一个命名的类型StringCollection的设置设置启动。点击点值列,并输入了几个字符串。使窗体类code是这样的:

Just an explanation for why this exception is thrown. You can repro the exception with this sample Windows Forms app. Start by adding a setting named "Setting" of type StringCollection. Click the dots in the Value column and enter a couple of strings. Make the form class code look like this:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
    }
    protected override void OnFormClosing(FormClosingEventArgs e) {
        Properties.Settings.Default.Setting[0] = DateTime.Now.ToString();
        Properties.Settings.Default.Save();
        base.OnFormClosing(e);
    }
}

调试+异常,剔为CLR例外,抛出该异常复选框。运行该窗体并关闭它,调试器将停止时,抛出异常。调用堆栈的顶部看起来是这样的:

Debug + Exceptions, tick the Thrown checkbox for CLR exceptions. Run the form and close it, the debugger will stop when the exception is thrown. The top of the call stack looks like this:

mscorlib.dll!System.Reflection.Assembly.nLoad(System.Reflection.AssemblyName fileName, string codeBase, System.Security.Policy.Evidence assemblySecurity, System.Reflection.Assembly locationHint, ref System.Threading.StackCrawlMark stackMark, bool throwOnFileNotFound, bool forIntrospection) + 0x2c bytes 
mscorlib.dll!System.Reflection.Assembly.InternalLoad(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, ref System.Threading.StackCrawlMark stackMark, bool forIntrospection) + 0x80 bytes   
mscorlib.dll!System.Reflection.Assembly.Load(System.Reflection.AssemblyName assemblyRef) + 0x1d bytes   
System.Xml.dll!System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null, out System.Xml.Serialization.XmlSerializerImplementation contract = null) + 0xcd bytes  
System.Xml.dll!System.Xml.Serialization.XmlSerializer.XmlSerializer(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null) + 0x105 bytes  

您可以看到XmlSerializer类狩猎包含的StringCollection类XML序列组装。该LoadGeneratedAssembly方法看起来是这个无聊位删除:

You can see the XmlSerializer class hunting for an assembly that contains the XML serializer for the StringCollection class. The LoadGeneratedAssembly method looks like this with the boring bits removed:

internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract)
{
    ...
    AssemblyName parent = GetName(type.Assembly, true);
    partialName = Compiler.GetTempAssemblyName(parent, defaultNamespace);
    parent.Name = partialName;
    parent.CodeBase = null;
    parent.CultureInfo = CultureInfo.InvariantCulture;
    try
    {
        serializer = Assembly.Load(parent);      // <=== here
    }
    catch (Exception exception)
    {
      ...
    }
  ....
}

和Compiler.GetTempAssemblyName():

And Compiler.GetTempAssemblyName():

internal static string GetTempAssemblyName(AssemblyName parent, string ns)
{
    return (parent.Name + ".XmlSerializers" + (((ns == null) || (ns.Length == 0)) ? "" : ("." + ns.GetHashCode())));
}

这是GetTempAssemblyName恶人在这种情况下。该StringCollection类生活在System.dll中装配的方法生成名为System.XmlSerializers。这种方法的目的是找到适合你自己的类的组装,通过Sgen.exe产生的之一。就像WindowsApplication1.XmlSerializers.dll为您的样品程序。但StringCollection是.NET Framework中的一类,它生成只是程序集的名称是无效的。这里实际上不是一个System.XmlSerializers.dll组件的框架。

This GetTempAssemblyName is the evil-doer in this case. The StringCollection class lives in the System.dll assembly, the method generates the name "System.XmlSerializers". This method is designed to find the assembly for your own classes, the one generated by Sgen.exe. Like WindowsApplication1.XmlSerializers.dll for your sample program. But StringCollection is a class in the .NET Framework, the assembly name it generates just isn't valid. There isn't actually a "System.XmlSerializers.dll" assembly in the framework.

有关在connect.microsoft.com这种行为反馈报告已经全部封闭,通过设计。这是,原来的设计师考虑的$ P $的成本pventing异常过高,决定只捕获异常。这一切工作正常,异常确实抓住了。你只是碰巧看到它,因为你得到了,抛出该异常复选框调试+异常对话框打开。

Feedback reports about this behavior at connect.microsoft.com have all been closed with "By Design". It was, the original designers considered the cost of preventing the exception too high and decided to just catch the exception. Which all works fine, the exception is indeed caught. You just happen to see it because you got the Thrown checkbox turned on in the Debug + Exceptions dialog.

使XML序列化code行为不同这里是不是一种选择。这本来是很容易足以让他们简单地过滤掉了System.dll程序集中的类型,但是这是一个潜在的永无休止的战斗,也有框架更大量组件。一个解决办法是使用自己的类来存储设置,而不是使用StringCollection的。

Making the Xml serialization code behave differently here is not an option. It would have been easy enough for them to simply filter out types in the System.dll assembly, but that's a potentially never-ending battle, there are a lot more assemblies in the framework. A workaround is to use your own class to store the setting instead of using a StringCollection.

这篇关于FileNotFoundException异常的ApplicationSettingsBase的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆