gpt4 book ai didi

asp.net-4.5 - UseLegacyPathHandling 未从 app.config 运行时元素正确加载

转载 作者:行者123 更新时间:2023-12-04 13:39:53 24 4
gpt4 key购买 nike

我正在尝试在我的应用程序中使用新的长路径支持。为了使用它,而不是强制客户在他们的机器上安装最新的 .NET 4.6.2 版本,一个人应该只将这些元素添加到他的 app.config(有关更多信息,请参见链接 https://blogs.msdn.microsoft.com/dotnet/2016/08/02/announcing-net-framework-4-6-2/):

<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
</startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
</runtime>

当我在我的执行项目中使用它时,它工作得很好。问题出在我的测试项目中(使用 Nunit)。我已将 app.config 添加到我的测试项目,就像我将其添加到执行项目一样。

使用 ConfigurationManager 类,我设法确保应用配置确实已加载(简而言之:使用我能够在单元测试中检索的应用设置)。

使用 ConfigurationManager.GetSection("runtime"),我什至设法确保运行时元素已正确加载(_rawXml 值与 app.config 中的值相同)。

但是(!)由于某种原因,应用程序配置运行时元素不会影响 UseLegacyPathHandling 变量,因此我所有的长路径调用都失败了。

我想这个问题在某种程度上与以下事实有关:测试项目变成了使用 Nunit 引擎加载的 dll,这是执行入口点。

我在另一个项目中遇到了完全相同的问题,这是一个由 Office Word 应用程序加载的 dll。我认为这两种情况下的问题是相同的,并且源于项目并不意味着成为执行入口点这一事实。

重要的是要了解我无法访问他们自己的执行(Word Office 或 Nunit),因此我无法自己配置它们。

是否可以选择以某种方式让 AppContextSwitchOverrides 从头开始​​动态加载?欢迎提出其他想法。

最佳答案

我一直遇到同样的问题,并且注意到同样没有加载该特定设置。

到目前为止,我得到的是设置缓存至少是部分原因。如果您检查它是如何实现的,禁用缓存对以后对值的调用没有影响(即,如果启用缓存并且在此期间访问了某些内容,那么它将始终被缓存)。

https://referencesource.microsoft.com/#mscorlib/system/AppContext/AppContext.cs

这似乎不是大多数设置的问题,但出于某种原因,在我第一次进入代码时,UseLegacyPathHandling 和 BlockLongPaths 设置已被缓存。

目前,我没有一个好的答案,但如果您在此期间需要一些东西,我为您准备了一个非常可疑的临时修复程序。使用反射,您可以修复程序集 init 中的设置。它按名称写入私有(private)变量,并使用特定值 0 使缓存无效,因此这是一个非常微妙的修复,不适合长期解决方案。

话虽如此,如果您暂时需要“正常工作”的东西,您可以检查设置,并根据需要应用 hack。这是一个简单的示例代码。这将是您在测试类中需要的方法。

    [AssemblyInitialize]
public static void AssemblyInit(TestContext context)
{
// Check to see if we're using legacy paths
bool stillUsingLegacyPaths;
if (AppContext.TryGetSwitch("Switch.System.IO.UseLegacyPathHandling", out stillUsingLegacyPaths) && stillUsingLegacyPaths)
{
// Here's where we trash the private cached field to get this to ACTUALLY work.
var switchType = Type.GetType("System.AppContextSwitches"); // <- internal class, bad idea.
if (switchType != null)
{
AppContext.SetSwitch("Switch.System.IO.UseLegacyPathHandling", false); // <- Should disable legacy path handling

// Get the private field that is used for caching the path handling value (bad idea).
var legacyField = switchType.GetField("_useLegacyPathHandling", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
legacyField?.SetValue(null, (Int32)0); // <- caching uses 0 to indicate no value, -1 for false, 1 for true.

// Ensure the value is set. This changes the backing field, but we're stuck with the cached value for now.
AppContext.TryGetSwitch("Switch.System.IO.UseLegacyPathHandling", out stillUsingLegacyPaths);
TestAssert.False(stillUsingLegacyPaths, "Testing will fail if we are using legacy path handling.");
}
}
}

关于asp.net-4.5 - UseLegacyPathHandling 未从 app.config 运行时元素正确加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40722086/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com