我有一个非常古老的应用程序,现在需要对Windows Server 2008友好。它是一个用作单例的用户应用程序。它使用HKLM部分注册表来读取和编写配置,并创建日志文件。
主要问题:如何让UAC的应用程序与最佳实践相结合?
我的初始方法是运行非升级的应用程序,如果需要更改配置,则用户手动重新启动它,升级,重新配置并重新启动到非升级。问题是,然后可以提升日志文件,然后非提升的应用程序无法写入它。可能的解决方法:
目前为止,第一个选项最好看,但如何检测高程?也许还有其他选择?也许有一些完全不同的方法?如果可能的话,我不想过多地更改代码。
答案 0 :(得分:1)
UAC是一个相当戏剧性的变化;在事实充满危险之后,试图将你的应用程序用来装鞋。将注册表和日志文件位置从机器区域更改为用户区域不是更容易吗?例如HKCU和CSIDL_APPDATA。如果这对您不起作用,那么用户只需要提升您的应用程序;您可以指定requireAdministrator清单。
答案 1 :(得分:1)
最佳做法是重写应用程序以使用每用户存储,除非您确实需要一个用户保存的内容影响其他用户。也就是说,答案“只有一个用户,因此每个用户和每个机器是相同的”被拒绝。在这种情况下,整个应用程序始终运行非提升,并带有清单以防止虚拟化。
下一个最佳做法是对应用程序进行分区。写入HKLM的代码位于单独的exe中,并具有请求提升的清单。 UI有一些警告(按钮或菜单项上的屏蔽),用户可以在其中运行此代码。使用ShellExecute启动单独的进程,它遵循清单。用户的体验是,大多数时候应用程序运行不升高,有时它的一部分似乎升高然后降低。这就是它的样子,但这实际上是不可能的 - 一个exe要么升高要么不升高。你可以通过两个前任来达到效果。
第三个最好的方法是将日志移动到相同的位置,无论您是否升高,并训练您的用户在需要时手动提升。我认为它根本不是一个好的解决方案,但它比训练它们更好,每次都在不同的地方手动提升和编写日志文件。我猜你是在“当前目录”下写的,它本身在Program Files下,并且你没有清单。然后,当没有提升时,您的应用程序将在虚拟商店下写入。如果用户需要查找日志文件,这实际上并不好。写入另一个文件夹 - AppData下的内容会很好。该位置不会被虚拟化。
检测您是否被提升的最简单方法是使用IsInRole来查看用户是否是管理员。稍微测试一下,即使管理员用户在应用程序未提升时也会返回false
,即使是因OTS提示而提升的非管理员也会返回true
。