为没有凭据的不同用户获取特殊文件夹

我正在编写一个卸载程序,作为该过程的一部分,我想为所有本地用户清理缓存,临时文件等。 该应用程序将升级为此工作。

我正在寻找的文件可以在特殊文件夹中找到,例如AppData\Local ,所以我需要路径。 对于当前登录的用户,这对于Environment.GetFolderPath是微不足道的。 但是,这不适用于其他用户。

根据referencesource.microsoft.com, GetFolderPath最终调用SHGetFolderPath ,而SHGetFolderPath又包含SHGetKnownFolderPath 。 这两个Win32 API都有一个可选的hToken参数,可以让我指定一个帐户令牌。

事实上,这将有效:

 private static string GetFolderPath(Guid knownfolderid, string user, string domain, string password) { const int LOGON32_PROVIDER_DEFAULT = 0; const int LOGON32_LOGON_INTERACTIVE = 2; SafeTokenHandle safeTokenHandle; if (!LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle)) throw new System.Security.Authentication.InvalidCredentialException(); IntPtr pPath; SHGetKnownFolderPath(knownfolderid, 0, safeTokenHandle.DangerousGetHandle(), out pPath); string result = System.Runtime.InteropServices.Marshal.PtrToStringUni(pPath); System.Runtime.InteropServices.Marshal.FreeCoTaskMem(pPath); return result; } 

…但它对我的用途来说是不切实际的 – 当然 – 我不希望卸载某些东西的管理员必须知道并提供每个用户名和密码。

所以:

  • 有没有办法获得适当的访问令牌, 无需知道用户的凭据?
  • 如果不这样做,有没有不同的方法来实现我的目标? 从注册表中读取信息似乎不安全 ,当然,硬编码文件夹名称也是如此。

假设修改应用程序以支持卸载程序还为时不晚,您可以在安装时在ProgramData中创建一个文件夹,然后每次启动应用程序时,它都可以为包含该路径的当前用户编写一个文件(s )到相关的目录和/或文件。 (您甚至可以在更新时对其进行改进,但对于在安装更新和卸载产品之间未登录的用户不起作用。)

你需要对安全性有点小心。 非管理员用户应该只对该文件夹具有“创建文件”访问权限,该文件夹应设置为不可inheritance。 这样他们就无法看到或操纵彼此的文件。 您可能还希望为CREATOR OWNER分配可inheritance的完全访问权限。

您还需要validation保存的路径信息,而不是盲目信任它,否则恶意用户可能会使您的卸载程序删除错误的文件。 我建议您检查您要删除的文件或文件夹是否属于拥有包含已保存路径信息的文件的同一个人,如果没有,请致电寻求帮助。 为了更加安全,您的应用程序还可以标记它创建的文件,这些文件应该在卸载时删除,可能使用备用数据流。