I'm writing a C# Windows application to update a .ini file for a legacy application. I don't have the source for the legacy application, so I cannot modify it.
The legacy application stores settings in a INI file in C:\Windows. This location cannot be changed.
To modify the INI settings I've been using these Windows functions:
[DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileString")]
private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
[DllImport("kernel32.dll", EntryPoint = "WritePrivateProfileString")]
private static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
The above functions don't seem to modify the INI file, however subsequent calls to "GetPrivateProfileString" show the correct/modified values.
Additionally I've even tried writing directly to the INI file using System.IO classes. This didn't seem to modify the INI file.
If I try to copy the file to the application's directory then write the INI settings, the correct values are written. If I then try to copy this modified file back to C:\Windows the original INI file doesn't seem get modified.
It seems like there's some type of INI file cache happening at the OS level?
If I manually edit the INI file using a text editor the INI file is updated.
As suggested on other forums I've also tried this code after writing the INI setting:
WritePrivateProfileString(null, null, null, filename);
My problem is that the legacy app doesn't pick up the INI file changes (even after restarting the legacy app).
Under UAC, applications with no UAC manifest that try to do things UAC prevents are subject to virtualization. This writes to a mirror location instead of the protected location. When you try to read, if there is a file in the mirror location, you get that file. In this way your app will work, even though it was written contradictory to the best practices of the time.
To find the mirror location, open a Windows explorer to the folder and look for a button in the toolbar that says Compatibility Files:

Perhaps this is enough for you - now that you know where to look you can trust virtualization and the app will work properly. If not, consider putting an external manifest on the application. A manifest saying asInvoker will prevent virtualization and the writes will fail. If the app has error handling (like falling back to another location) perhaps this is good. A manifest saying requireAdministrator will prevent virtualization and the writes will succeed. However the UAC consent will probably annoy your users.
(The image, btw, is from a blog entry of mine that talks a bit more about virtualization. http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx)
I find with many apps, a single run as administrator gets my settings in place and after that I can run without elevating. In that case train your users to right-click, run as administrator.
This started with Vista to increase security. If an app tries to write to a location that is protected (like ini files written to the app's folder under ProgramFiles, or to the Windows folder, the app's reads and writes to that file are redirected to a folder in C:\Users{username}\AppData\Local\VirtualStore\
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With