how to get 32 bit application data folder from 64 bit application on 64 bit Machine using c# code

2k Views Asked by At

I am facing very strange issue:

I got a 64 bit c#.net application on 64 bit Windows Server 2008 R2 machine and it is being invoked by a Windows Service and it is started under Local System User, Moreover,this 64 bit c#.net application launches 32 bit java application and this java application has application data folder to C:\Windows\SysWOW64\config\systemprofile\AppData. 64 bit c#.net application has app data folder to C:\Windows\System32\config\systemprofile\AppData

So for 32 bit application app data folder is (in case of Local system User):-C:\Windows\SysWOW64\config\systemprofile\AppData

and for 64 bit application app data folder is(in case of Local system User):-C:\Windows\System32\config\systemprofile\AppData

Please Note: this is not typing mistake that they refer to opposite folders(it is a decision by microsoft for 64 bit OS), you can read https://msdn.microsoft.com/en-us/library/aa384187.aspx for detailed explanation.

Now, I need to write few files to 32 bit app data folder from 64 bit application as these files would be used by 32 bit java application.

So, I need to know How I can get 32 bit app data folder from 64 bit application using c#.net.

Important Note: this issue would be faced when application is launched under local system user (i.e. application has been launch by window services) and there won't be any issue when a user explicitly launches the application beacause in this case,user app data folder would be same for 64 bit and 32 bit application.

4

There are 4 best solutions below

1
LPs On

Are you using "shortcut" keyword to point appdata directory, eg %APPDATA%? Could you use a direct path, eg @"C:\Users\%username%\AppData\Local"

3
Sebastian Baumhekel On

You first check if you actually are running inside of a 64 bit process on a 64 bit OS. And if so, you construct the path yourself. Otherwise you can just retrieve the system path and append your target path.

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");

Please note that using EnvironmentIs64BitOperatingSystem and Environment.Is64BitProcess requires at least .NET-Framework 4.

2
Harry Johnston On

The simplest solution is to rebuild the C# application as 32-bit, or to use 64-bit Java.

If you can't do either, create a 32-bit application that does nothing but look up the application data path, and run it from your C# application. The 32-bit application could be written in C, C#, or Java.

0
Alex Martin On

This is the same answer as #2 above (via Sebastian Baumhekel), with some errors corrected. I am on Win 7 and have the same issue. As some have pointed out this may not be future OS safe... However it solves my current issue.

The issue is on 64bit Win7 when you run a 32bit Windows Service as Local System user and ask for this folder:

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

It returns the 64bit version (with System32):

C:\Windows\System32\config\systemprofile\AppData\

Main point of clarification (as OP states):

SysWOW64 gets 32bit application data...

System32 gets 64bit application data...

This from OP link:

https://learn.microsoft.com/en-us/windows/desktop/WinProg64/file-system-redirector

I just wasted 4 hours of my life getting to the bottom of this so I wanted to clarify!

    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");
        ...