我面临着一个非常奇怪的问题:
我在64位Windows Server 2008 R2机器上得到了一个64位c#.net应用程序,它正在由Windows服务调用,并在本地系统用户下启动。此外,这个64位c#.net应用程序启动了32位java应用程序,这个java应用程序的应用程序数据文件夹为c:\Windows\SysWOW64\config\systemprofile\AppData。64位c#.net应用程序的应用程序数据文件夹位于c:\Windows\System32\config\systemprofile\AppData
因此,对于32位应用程序,应用程序数据文件夹是(在本地系统用户的情况下):-C:\Windows\SysWOW64\config\systemprofile\AppData
对于64位应用程序,应用程序数据文件夹是(如果是本地系统用户):-C:\Windows\System32\config\systemprofile\AppData
请注意:这不是打字错误,他们引用了相反的文件夹(这是微软对64位操作系统的决定),你可以阅读https://msdn.microsoft.com/en-us/library/aa384187.aspx详细说明
现在,我需要从64位应用程序向32位应用程序数据文件夹写入一些文件,因为这些文件将被32位java应用程序使用
所以,我需要知道如何使用c#.net.从64位应用程序中获取32位应用程序数据文件夹
重要提示:当应用程序在本地系统用户下启动时(即应用程序已由窗口服务启动),将面临此问题,并且当用户明确启动应用程序时不会有任何问题,因为在这种情况下,64位和32位应用程序的用户-应用程序数据文件夹将相同
首先要检查您是否真的在64位操作系统上的64位进程内部运行。如果是这样的话,你自己构建这条路。否则,您可以只检索系统路径并附加您的目标路径。
String path;
//detect if the current application is 64 bit and running on a 64 bit system
//NOTE: needs .NET Framework 4 to work
if (Environment.Is64BitOperatingSystem && Environment.Is64BitProcess)
{
path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysWOW64");
}
else
{
path = Environment.GetFolderPath(Environment.SpecialFolder.System);
}
//append your target path
path = Path.Combine(path, @"configsystemprofileAppData");
请注意,使用EnvironmentIs64BitOperatingSystem
和Environment.Is64BitProcess
至少需要.NET Framework 4。
最简单的解决方案是将C#应用程序重建为32位,或者使用64位Java。
如果两者都做不到,请创建一个32位应用程序,它只查找应用程序数据路径,然后从C#应用程序中运行它。32位应用程序可以用C、C#或Java编写。
您是否使用"shortcut"关键字指向appdata目录,例如%appdata%?你能使用一个直接路径吗,例如@"C:\Users\%username%\AppData\Local"
这与上面的#2答案相同(通过Sebastian Baumhekel),并更正了一些错误。我在Win 7上,也有同样的问题。正如一些人所指出的,这可能不是未来操作系统安全的。。。然而,它解决了我目前的问题。
当您以本地系统用户的身份运行32位Windows服务并请求此文件夹时,问题出现在64位Win7上:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
它返回64位版本(带有System32):
C:WindowsSystem32configsystemprofileAppData
澄清要点(如OP所述):
SysWOW64获取32位应用程序数据。。。
System32获取64位应用程序数据。。。
这来自OP链接:
https://learn.microsoft.com/en-us/windows/desktop/WinProg64/file-system-redirector
我只是浪费了我生命中的4个小时来弄清真相,所以我想澄清一下!
public 32bitWindowsServiceOn64bitWindows()
{
// Note: this service is configured to run as "Local System" user...
string appdata;
// need to do this, because this runs as Local System user...
// which gets the wrong SpecialFolder.ApplicationData (ie, System32 for 64bit apps) should be SysWOW64 (for 32bit apps)
if (Environment.Is64BitOperatingSystem && Environment.Is64BitProcess)
{
// the application is a 64 bit app
appdata = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32");
}
else
{
// the application is a 32 bit app
appdata = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysWOW64");
}
// Append your target path. Do you want Local or Roaming?
appdata = Path.Combine(appdata, @"configsystemprofileAppDataRoamingMyApp");
//appdata = Path.Combine(appdata, @"configsystemprofileAppDataLocalMyApp");
...