为什么Configuration.FilePath返回不存在的文件?

时间:2014-02-19 17:10:29

标签: c# windows-services syswow64

我有一个用C#(.NET 4.5)编写的Windows服务。此服务具有user范围设置,用于保存计时器变量。为了调试服务,我需要更新此变量,因此我需要知道服务的user.config文件所在的位置。因此,我在服务的OnStart()方法中添加了以下代码:

Logger.InfoFormat("user.config at \"{0}\"", ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath);

转储到我的日志文件中的是以下路径:

C:\Windows\system32\config\systemprofile\AppData\Local\company\service.exe_Url_randomcharacters\1.0.0.0\user.config

但是当我尝试打开该文件时,它不存在。在进行Windows搜索后,我找到了实际文件:

C:\Windows\SysWOW64\config\systemprofile\AppData\Local\company\service.exe_Url_randomcharacters\1.0.0.0\user.config

这是为什么?我假设有一些32位/ 64位兼容性魔法,但是获得实际路径的正确代码(如果有的话)是什么?

其他信息,如果有帮助:该服务在Windows Server 2008 R2 64位计算机上运行,​​并且是通过installutil安装的。我不确定是否使用了32位或64位版本的installutil - 这会有所不同吗?

1 个答案:

答案 0 :(得分:2)

这种情况正在发生,因为C:\ Windows \ system32是64位和32位进程的不同目录。 32位进程在C:\ Windows \ system32中查看C:\ Windows \ SysWOW64的内容。这很疯狂,但这就是微软决定在许多应用程序中提供与硬编码C:\ Windows \ system32的兼容性,并允许为32位和64位进程加载正确版本的.dll(因此64位dll在C:\ Windows中\ system32和32bit dll在C:\ Windows \ SysWOW64中。) 默认情况下用于服务的本地系统帐户在C:\ Windows \ system32中具有配置文件 - 因此32位和64位服务在%LOCALAPPDATA%中查看应用程序应该存储数据的不同文件。因此,例如当您的64位服务执行32位进程时,子进程不会在%LOCALAPPDATA%中查看父进程为其准备的文件。

有几种解决方法:

  • 您可以从其他用户启动服务(服务/属性/登录/登录为:此帐户) - 但在这种情况下,您必须提供密码,如果密码将被更改或过期服务将无法开始,直到密码也将被更改为服务。
  • 您可以使用其他位置来存储数据,而不是%LOCALAPPDATA%,这也不总是可以接受。
  • 您可以使用您的设置创建到目录的联结点 - 因此32位和64位应用程序将看到相同的目录:
    • 运行" psexec.exe -i -s cmd.exe"作为管理员(psexec是Sysinternal's PsTools的一部分) - in将从系统帐户打开命令提示符(这也是调试服务的好方法)
    • exec" mklink / J%SystemRoot%\ SysWOW64 \ config \ systemprofile \ AppData \ Local \ company%LOCALAPPADATA%\ company"

没有一种解决方法是完美的,但它们提供了相对简单的方法来处理这种疯狂。