简体   繁体   中英

C# Windows Program writes files to “sysWOW64” and to “Program Files(x86)”. Using VS Setup Projects. 32bit App on 64bit System

Could someone tell me, why my program writes/reads files to/from both folders after I installed it using VS Setup Projects? On first start, when I launch the program and save something in my program to a file, it writes it to:

C:\\Users\\UserName\\AppData\\Local\\VirtualStore\\Program Files (x86)\\Company Name\\Program Name\\"

After setup "run on system start", I restart the computer and the Program starts, but this time it reads and writes from/into this folder:

C:\\Users\\UserName\\AppData\\Local\\VirtualStore\\Windows\\SysWOW64

So that it loads wrong values or nothing on second start. It looks like it depends on how I start the Program, via Desktop Symbol or by Autorun on Systemstart.

How can I prevent this and how do I let the program always read/write from the same folder? I would prefer to save the files always in the root folder, where the exe is (C:\\Program Files(x86)\\CompanyName\\ProgramName).

I think the problem is somewhere in VS Setup Projects or it is because it is a 32bit Application running on a 64bit System. I already looked for solutions in other questions, but it didn't help, instead it didn't read anything. Hope someone can help me, thank you!

That's how I write a file: File.WriteAllText(@"mailstate2", "true"); I don't give a path... I just want it to be saved in the root folder...

You've actually got a couple different things going on here. All are related to how windows runs programs and protects critical portions of the filesystem from malicious tampering.

First off, programs can be started from any directory. If you don't specify a specific location to write the file to, then it will be written relative to whichever directory the program was started from. You can test this by setting up a shortcut to your program and changing the shortcut's 'Start in' property. So, the 'Start in' folder is different in your desktop shortcut from what is used by Autorun.

Second, only Elevated users and processes can actually modify certain windows directories. These include the Program Files , Program Files (x86) , and Windows folders, amongst others. If an un-elevated process attempts to write a file into one of these directories, windows automatically redirects them to the same folder under the windows VirtualStore directory . This allows legacy programs that used to read-write from these protected locations to keep working while still protecting executables from being overwritten by malware. In any case, this silent redirection is why your program winds up writing to very strange locations.

Depending on what kind of data you're looking to write there are several locations that would be appropriate to write your data that don't involve the virtual store.

  • If it is data that your user might want to copy to another computer or back up, then it might be appropriate to make a folder in his Documents folder, though personally I hate how many programs do that to me. If you find yourself doing this ask yourself if there's some way you can give the user the option of where to store this data. Maybe through a preference page or first-run configuration.
  • If it is preferences type data that individual computer users may want to customize independently from each other, but they don't need to see or be aware of, then using the user's AppData folder ( C:\\Users\\username\\AppData\\ ) is appropriate. Note that the AppData folder contains three different sub-folders: Roaming, Local, and LocalLow. Here's an excellent SuperUser topic on the differences between them .
  • If it is application data that needs to be preserved irrespective of users, then the ApplicationData folder ( C:\\ProgramData ) is appropriate, but you might need to set the permissions on any files\\directories you create in there to give all users access to them. Also note that there are security concerns that go along with doing so.

Here's a couple useful links that a quick google search pulled up that might get you started thinking in the right direction.

Damien has the main point here: you must be elevated (admin) to write/update files in shared common folders like AppData and program files (and many others too). The other issue is the virtualization that's done so that your program doesn't simply crash when it violates security by doing that - it writes to a virtual store. This is the kind of thing a search will show you:

https://www.curlybrace.com/words/2010/09/09/windows-vista7-file-system-virtualization/

The simple solution to this is to give your program an elevation manifest if it needs to run elevated to write/update files in the AppData folder. This kind of thing:

https://blogs.msdn.microsoft.com/nikhiln/2007/04/19/using-manifests-to-elevate-an-application-in-vista/

although Visual Studio should give you IDE support for a manifest so that your code has requestedExecutionLevel level=“requireAdministrator. It will ask for elevation when it starts, as do all programs on UAC systems that require it.

The presence of a manifest also turns off virtualization, so your app will crash instead of being redirected to virtualstore (if you violate file writes to restricted locations).

If you require limited users to be able to run your app then choose another location for your files, which ashbygeek has referred to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM