无法修改c:\ windows目录中的.ini文件

我正在编写一个C#Windows应用程序来更新遗留应用程序的.ini文件。 我没有遗留应用程序的源代码,所以我无法修改它。

旧应用程序将设置存储在C:\ Windows中的INI文件中。 此位置无法更改。

要修改INI设置,我一直在使用这些Windowsfunction:

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

上述函数似乎不会修改INI文件,但是后续调用“GetPrivateProfileString”会显示正确/修改的值。

另外,我甚至尝试使用System.IO类直接写入INI文件。 这似乎没有修改INI文件。

如果我尝试将文件复制到应用程序的目录然后写入INI设置,则会写入正确的值。 如果我然后尝试将此修改后的文件复制回C:\ Windows,原始的INI文件似乎不会被修改。

似乎在操作系统级别发生了某种类型的INI文件缓存?

如果我使用文本编辑器手动编辑INI文件,则会更新INI文件。

正如在其他论坛上所建议的那样,我在编写INI设置后也尝试了这段代码:

 WritePrivateProfileString(null, null, null, filename); 

我的问题是遗留应用程序没有获取INI文件更改(即使重新启动旧应用程序后)。

在UAC下,没有UAC清单的应用程序尝试执行UAC防止的操作会受到虚拟化的影响。 这将写入镜像位置而不是受保护的位置。 当您尝试读取时,如果镜像位置中有文件,则会获得该文件。 通过这种方式,您的应用程序将起作用,即使它与当时的最佳实践相矛盾。

要查找镜像位置,请打开该文件夹的Windows资源管理器,然后在工具栏中查找“兼容文件”中的按钮: UAC虚拟化

也许这对您来说已经足够了 – 现在您知道在哪里可以看到您可以信任虚拟化并且应用程序可以正常运行。 如果没有,请考虑在应用程序上放置外部清单。 一个asInvoker的清单将阻止虚拟化,写入将失败。 如果应用程序有error handling(如回到另一个位置)也许这很好。 清单说requireAdministrator将阻止虚拟化,写入将成功。 但是,UAC同意可能会惹恼您的用户。

(图像,顺便说一句,来自我的一篇博客文章,它更多地讨论了虚拟化.http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx )

我发现有许多应用程序,管理员进行一次运行就可以实现我的设置,之后我可以在不提升的情况下运行。 在这种情况下,训练您的用户右键单击,以管理员身份运行。

这始于Vista,以提高安全性。 如果应用程序尝试写入受保护的位置(如在ProgramFiles下写入应用程序文件夹的ini文件或Windows文件夹,则应用程序对该文件的读取和写入将重定向到C:\ Users {username中的文件夹} \应用程序数据\本地\ VirtualStore \

这些值被写入了一些驻留在其他地方的“镜像”文件 – 这是在幕后执行的魔法的一部分,以便在仍然制作更安全的操作系统时不破坏旧版应用程序…请参阅http://technet.microsoft。 COM / EN-US /库/ dd837644%28WS.10%29.aspx