【问题标题】:Auto-Generated AppData/Local folder being "incorrectly" created自动生成的 AppData/Local 文件夹被“错误地”创建
【发布时间】:2022-01-16 15:47:50
【问题描述】:

当我运行 .net exe 时,会创建一个相应的文件夹 C:\Users\UserName\AppData\Local\AppName

在这个文件夹内,创建了另一个文件夹AppName_Url_ABCXYZ

在此文件夹中,为 .net exe 0.2.28.0 的程序集版本创建了另一个文件夹

谁能解释一下windows是如何决定创建二级文件夹AppName_Url_ABCXYZ的?

当我增加我的程序集版本并执行单个文件发布并运行生成的 exe 时遇到问题,会创建一个包含新程序集版本文件夹的新 AppName_Url_ABCXYZ 文件夹。

这会导致问题,因为它破坏了Properties.Settings.Default.Upgrade() 的功能,因为要升级的设置不再位于预期的目录中

好:

-AppData
 -Local
  -MyApp
   -MyApp_Url_ABCXYZ
    -0.2.13.0
    -0.2.14.0
    -0.2.15.0

不好:

-AppData
 -Local
  -MyApp
   -MyApp_Url_ABC1
    -0.2.13.0
   -MyApp_Url_ABC2
    -0.2.14.0
   -MyApp_Url_ABC3
    -0.2.15.0

更新:

@Richard Deeming 提供的信息表明,appdata 文件夹的哈希部分是这样生成的:

var uri = "file:///" + fullExePath; //or 'assemblyName.CodeBase' if vshost (you can check the 'FriendlyName')
uri = uri.ToUpperInvariant();

var ms = new MemoryStream();
var bSer = new BinaryFormatter();
bSer.Serialize(ms, uri);
ms.Position = 0;
var sha1 = new SHA1CryptoServiceProvider();
var hash = sha1.ComputeHash(ms);
var hashstring = ToBase32StringSuitableForDirName(hash);

这没有意义,因为 exe 路径没有改变

全新的 WPF .net 6 应用程序和增加程序集版本不会出现此问题,因此它是特定于我的应用程序的问题。

在 Windows 资源管理器中检查生成的 exe 并没有帮助,它们看起来相同。

更新:

我一直无法确定为什么我的项目会出现这种情况。我什至不知道如何调试它。我从未对这种行为进行任何有意的更改。

【问题讨论】:

  • 你使用的是点击一次吗?
  • 没有。只是 VS 中的发布选项
  • AFAIK 它应该可以工作,因为在Upgrade() 的功能中考虑了此类更改。根据this answer,您需要在用户设置中设置一个标志值,以便仅在发布新版本时进行升级;你试过吗?你能准确地发布你如何调用Upgrade() 方法吗?
  • 完全如该答案中所述。问题是生成的 appdata 文件夹被放入一个仅包含该版本的新文件夹中。以前的版本在它自己的文件夹中。 Upgrade() 方法似乎只适用于同一文件夹中的版本,因此我的问题
  • 您使用的是 .NET Framework 还是新堆栈(又名 .NET Core)?

标签: c# .net windows


【解决方案1】:

如果我的理解是正确的,有问题的文件夹 (C:\Users\UserName\AppData\Local\AppName\AppName_Url_ABCXYZ) 用于存储 user.config 设置。请检查以下线程:

How to change the predefined userconfig directory of my .NET application?

Custom path of the user.config

以下是常见问题解答中的引述: https://docs.microsoft.com/en-us/archive/blogs/rprabhu/client-settings-faq

user.config 文件的确切路径如下所示:

<Profile Directory>\<Company Name>\<App Name>_<Evidence Type>_<Evidence Hash>\<Version>\user.config

在哪里

<Profile Directory> - 是漫游配置文件目录或 本地的。设置默认存储在本地 user.config 文件。要将设置存储在漫游 user.config 文件中,您需要 使用 SettingsManageabilityAttribute 标记设置 SettingsManageability 设置为漫游。

<Company Name> - 通常是由 AssemblyCompanyAttribute(注意字符串被转义 并根据需要截断,如果没有在程序集中指定,我们 有一个后备程序)。

<App Name> - 通常是由 AssemblyProductAttribute(与公司名称相同的注意事项)。

<Evidence Type> 和 <Evidence Hash> - 来自应用程序的信息 域证据以提供适当的应用程序域和程序集隔离。

<Version> - 通常是在 程序集版本属性。这需要隔离不同的 并排部署的应用版本。

文件名总是简单的user.config。

如果您想以编程方式访问路径,您可以使用 配置管理 API(您需要添加对 System.Configuration.dll)。

路径构建算法必须满足一定的严谨性 安全性、隔离性和鲁棒性方面的要求。虽然我们 试图通过使路径尽可能容易被发现 使用友好的、应用程序提供的字符串,这是不可能的 保持路径完全简单,而不会遇到诸如 与其他应用程序冲突、欺骗等。

LocalFileSettingsProvider 不提供更改 存储设置的文件。请注意,提供者本身 首先不确定配置文件的位置 - 它是 配置系统。如果您需要将设置存储在 由于某种原因不同的位置,推荐的方法是写 您自己的 SettingsProvider。

看起来微软故意没有提供配置配置文件路径以避免冲突的方法。 上面提到的 SO 线程似乎提供了一些关于实现自定义 SettingsProvider 的说明。

在您的情况下,<Evidence Hash> 部分在更新版本后会有所不同。这是另一个描述可能原因的线程: https://social.msdn.microsoft.com/Forums/vstudio/en-US/d87a0add-00ba-4074-8ef3-cf085e1122eb/userscope-settings-path-changed-after-upgrade?forum=netfxbcl

Evidence Hash 改变了,因为这个值受两个因素影响,详情请check this link,

1.StrongName

2.网址

如果这些都不可用,请使用 .exe 路径。

<Evidence Type> 可以是 URL、StrongName 或路径,具体取决于可用于散列的证据。在有问题的路径中,我可以看到它设置为 Url。正如我在“Programming .NET Security”一书中发现的那样,Url 证据表示从中加载程序集的 URL。如果它是从磁盘加载的,它将是 file:// URL。虽然没有用例子检查过。

可能是 URL 更改或 EXE 路径更改影响了哈希值。

另外,还要检查程序集强名是否发生了变化。

强名称由程序集的标识(其简单的文本名称、版本号和文化信息(如果提供))以及公钥和数字签名组成。它是使用相应的私钥从程序集文件生成的。 (程序集文件包含程序集清单,其中包含构成程序集的所有文件的名称和哈希值。) https://docs.microsoft.com/en-us/dotnet/standard/assembly/create-use-strong-named

【讨论】:

  • 谢谢你,这是很好的信息
  • URL 到底指的是什么?这是一个 WPF 桌面项目
  • 这里还有一个关于计算哈希值的线程:stackoverflow.com/questions/24660121/… 在我看来,最好先检查路径差异。
  • 还是很奇怪。我的应用程序的路径没有改变。 C:\some\dir\MyApp.exe 是常量。
  • 正如我在“Programming .NET Security”一书中发现的那样,Url 证据表示从中加载程序集的 URL。如果它是从磁盘加载的,它将是 file:// URL。虽然没有用例子检查过。
【解决方案2】:

Download the entire project package here – ConsoleApp1.zip

为了演示,让我们创建一个简单的控制台应用程序:

并添加一个链接:

<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />

我们还将添加 Settings.settings 项目属性文件。 结果,我们得到了一个如下配置的项目:

在调试模式下编译并运行ConsoleApp1.exe的结果后,我们沿着路径C:\Users\Administrator\AppData\Local\ConsoleApp1得到如下图:

在这个文件夹里面会有一个文件夹,里面有程序的版本号:

在编译发布版本并运行ConsoleApp1.exe的结果时,我们沿着路径C:\Users\Administrator\AppData\Local\ConsoleApp1得到如下图:

在这个新文件夹中还会有一个文件夹,其中包含程序的版本号:

需要注意的是,程序的调试版和发布版会创建不同的文件夹。

当您更改项目版本时,新版本将分别出现在调试和发布文件夹中:

调试程序和发布程序是同一个项目的不同编译“版本”,并且创建了不同的URL来分隔它们。

Download the entire project package here – ConsoleApp1.zip

【讨论】:

  • 感谢您的全面报道。不幸的是它不能解决问题:(when i increment my assembly version and perform a single file publish and run the resulting exe, a new AppName_Url_ABCXYZ folder is created containing the new assembly version folder.
  • 您需要确保 1. Visual Studio 2022 更新到最新版本; 2.然后我需要更详细的环境信息:windows,Visual Studio的版本; 3. 有完整的测试项目就好了。
  • Windows 10 Pro 20H2 19042.1466 VS 2022 64-bit 4.8.04084 我没有测试项目,只有我的真实应用程序,我无法分享。
  • 请检查我之前提供的项目是如何工作的。它确实有效,并且似乎避免了您试图避免的问题。您可以从我原始答案顶部和底部的链接下载它。为了帮助解决您的问题,我首先需要重现您描述的行为。没有您的帮助,这是不可能的。如果您无法共享您的项目,您可以创建一个测试项目,您可以共享并隔离您要解决的问题。
  • 再次感谢。如果我知道如何在新项目中重现问题,我可能会知道如何解决该问题。我不知道为什么这种行为会发生在我的项目中,而不是新的示例项目中。我正在寻求帮助以发现为什么会在我的项目中发生这种情况-我不是在寻求解释它的工作原理。
猜你喜欢
  • 2016-05-26
  • 2019-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-07
  • 2018-01-09
  • 2013-04-17
  • 2011-03-19
相关资源
最近更新 更多