2011-07-25 148 views
3

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

传统应用程序将设置存储在C:\ Windows中的INI文件中。这个位置不能改变。

要修改我一直在使用这些Windows功能INI设置:

[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文件的更改(甚至在重新启动后传统应用程序)。

回答

4

在UAC下,没有UAC清单的应用程序尝试执行UAC防止操作时会受到虚拟化影响,这会写入镜像位置而不是受保护位置当您尝试读取时,如果镜像位置中有文件,那么您将获得该文件。这样,即使您的应用程序与当时的最佳做法相矛盾,您的应用程序也可以正常工作。

要找到镜像位置,请打开Windows资源管理器添加到该文件夹​​,然后在工具栏中找到一个说明兼容性F的按钮iles: UAC virtualization

也许这对于您来说已经足够了 - 现在您知道在哪里可以信任虚拟化并且该应用程序将正常工作。如果没有,请考虑在应用程序上添加外部清单。清单说asInvoker将阻止虚拟化,写入将失败。如果应用程序有错误处理(如回落到另一个位置),这可能是好的。清单requireAdministrator将阻止虚拟化并且写入将成功。但是,UAC同意可能会惹恼您的用户。

(图像,顺便说一句,从我的博客文章,讨论更多的关于虚拟化。http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx

我发现许多应用程序,以管理员身份跑单变到位后,我的设置我可以跑步而不提升。在这种情况下,训练您的用户以右键单击,以管理员身份运行。

3

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

+0

当我通过文本编辑器保存INI文件时,它更新C:\ Windows \ XXX.ini文件。为什么这不会更新C:\ Users {用户名} \ AppData \ Local \ VirtualStore \版本? – FattyPotatoes

+0

我认为这可能是因为重定向的UAC代码知道应用程序是否是遗留的(pre vista),并且只有在应用程序是遗留的时才重定向。 – hatchet

+0

@FattyPotatoes它永远不会更新两个。我的猜测是你的文本编辑器正在运行提升 - 也许是因为你提出了这个要求,或者是因为你以管理员身份登录(不仅仅是管理员组中的某个帐户)。抬起的文本编辑器可以写入该位置。 –