C#.NET – 如何确定目录是否可写,有无UAC?

我正在研究一个需要将文件复制到文件系统上给定目录的软件。 它需要适用于UAC感知操作系统(Vista,7)以及XP。 为了解决写入需要UAC提升的目录的问题,应用程序实际上启动了另一个进程,其中包含一个表明需要UAC的清单。 这会生成提示,然后在用户确认时执行复制。

从我所看到的,一个目录可以有三种不同的逻辑权限状态 – 可写,没有UAC提升,可写入UAC提升且不可写。

我的问题是:对于给定目录,如何可靠地确定当前用户是否可以将文件复制(并可能覆盖)到该目录,如果可以,我如何确定是否需要UAC提升?

在XP上,这可能就像检查是否授予“允许写入”权限一样简单,但在Vista / 7上,有些目录未授予此权限,但UAC仍然可以执行此操作。

我们有一个WriteAccess文件的方法,你可以为目录调整它(Directory.GetAccessControl等)

///  Checks for write access for the given file. ///  /// The filename. /// true, if write access is allowed, otherwise false public static bool WriteAccess(string fileName) { if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) != 0) return false; // Get the access rules of the specified files (user groups and user names that have access to the file) var rules = File.GetAccessControl(fileName).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier)); // Get the identity of the current user and the groups that the user is in. var groups = WindowsIdentity.GetCurrent().Groups; string sidCurrentUser = WindowsIdentity.GetCurrent().User.Value; // Check if writing to the file is explicitly denied for this user or a group the user is in. if (rules.OfType().Any(r => (groups.Contains(r.IdentityReference) || r.IdentityReference.Value == sidCurrentUser) && r.AccessControlType == AccessControlType.Deny && (r.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData)) return false; // Check if writing is allowed return rules.OfType().Any(r => (groups.Contains(r.IdentityReference) || r.IdentityReference.Value == sidCurrentUser) && r.AccessControlType == AccessControlType.Allow && (r.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData); } 

希望这可以帮助。

只需通过尝试操作即可处理不带高程的可写。 当失败时,你必须通过UAC提升区分不可写和可写,这可能很难。

我不认为我希望程序试图为我解决这个问题(因为它们不可避免地会经常出错)。

我认为用这些假设设计它是安全的:

  • 管理员有时会将其作为受限制的帐户运行到他们不信任的试用软件 – >如果您的应用程序要对需要UAC的计算机进行侵入式更改,而不是提升。
  • 提升的管理员可以编写文件(毕竟他们是管理员) – >不需要实际的ACL检查,检测受限制的令牌就足够了。
  • 用户可以使用其他帐户提升,或者可以要求同事完成UAC所需的操作 – >检查受限制的令牌会错过这些情况。
  • 其他可恢复的东西导致访问被拒绝,包括正在使用的文件 – >有时正确的做法是使用相同的受限权限重试。

总而言之,我建议尝试操作AsInvoker,如果访问被拒绝,则会提示解释Windows拒绝操作,可能的原因是:文件使用中,需要提升,需要管理员凭据,并且给用户三个纽扣:

  • 取消
  • 使用当前凭据重试
  • (盾牌图标)提升权限并重试