Как получить 32-битную папку данных приложения из 64-битного приложения на 64-битной машине с помощью кода C#
Я сталкиваюсь с очень странной проблемой:
Я получил 64-разрядное приложение C#.net на 64-разрядной машине с Windows Server 2008 R2, и оно вызывается службой 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
Обратите внимание: ошибка не связана с тем, что они ссылаются на разные папки (это решение от Microsoft для 64-битных ОС), вы можете прочитать https://msdn.microsoft.com/en-us/library/aa384187.aspx для детальное объяснение.
Теперь мне нужно записать несколько файлов в папку данных 32-битного приложения из 64-битного приложения, так как эти файлы будут использоваться 32-битным Java-приложением.
Итак, мне нужно знать, как я могу получить 32-битную папку данных приложения из 64-битного приложения, используя C#.net.
Важное примечание: эта проблема будет возникать, когда приложение запускается от имени пользователя локальной системы (т. Е. Приложение было запущено оконными службами), и не будет никаких проблем, когда пользователь явно запускает приложение, потому что в этом случае папка данных приложения пользователя будет одинаковым для 64-битных и 32-битных приложений.
3 ответа
Сначала вы проверяете, действительно ли вы работаете внутри 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, @"config\systemprofile\AppData");
Обратите внимание, что с помощью EnvironmentIs64BitOperatingSystem
а также Environment.Is64BitProcess
требует как минимум.NET-Framework 4.
Самое простое решение - перестроить приложение C# как 32-битное или использовать 64-битную Java.
Если вы не можете этого сделать, создайте 32-разрядное приложение, которое ничего не делает, кроме поиска пути к данным приложения, и запустите его из своего приложения C#. 32-битное приложение может быть написано на C, C# или Java.
Используете ли вы ключевое слово "ярлык", чтобы указать каталог appdata, например,%APPDATA%? Не могли бы вы использовать прямой путь, например, @"C:\Users\%username%\AppData\Local"
Это тот же ответ, что и № 2 выше (через Себастьяна Баумхекеля), с некоторыми исправленными ошибками. Я на Win 7 и у меня та же проблема. Как уже отмечалось, это может быть небезопасно для будущей ОС... Однако это решает мою текущую проблему.
Проблема связана с 64-битной Win7, когда вы запускаете 32- битную службу Windows в качестве пользователя локальной системы и запрашивает эту папку:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
Возвращает 64-битную версию (с System32):
C:\Windows\System32\config\systemprofile\AppData\
Основная точка разъяснения (как утверждает ОП):
SysWOW64 получает 32- битные данные приложения...
System32 получает данные 64-битных приложений...
Это из OP ссылка:
https://docs.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, @"config\systemprofile\AppData\Roaming\MyApp");
//appdata = Path.Combine(appdata, @"config\systemprofile\AppData\Local\MyApp");
...