C#Winform对文件夹的权限判断及处理
C#Winform对⽂件夹的权限判断及处理WindowsIdentity类可以获取当前执⾏者的⾝份信息
27.
对执⾏的程序设定执⾏⾝份权限
如果程序不是以管理员⾝份运⾏,操作本地⽂件会提⽰:System.UnauthorizedAccessException异常
Vista 和 Windows 7 操作系统为了加强安全,增加了 UAC(⽤户账户控制) 的机制,如果 UAC 被打开,⽤户即使是以管理员权限登录,其应⽤程序默认情况下也⽆法对系统⽬录,系统注册表等可能影响系统运⾏的设置进⾏写操作。这个机制⼤⼤增强了系统的安全性,但对应⽤程序开发者来说,我们不能强迫⽤户去关闭UAC,但有时我们开发的应⽤程序⼜需要以 Administrator 的⽅式运⾏,即 Win7 中以 as administrator ⽅式运⾏,那么我们怎么来实现这样的功能呢?
我们在 win7 下运⾏⼀些安装程序时,会发现⾸先弹出⼀个对话框,让⽤户确认是否同意允许这个程序改变你的计算机配置,但我们编写的应⽤程序默认是不会弹出这个提⽰的,也⽆法以管理员权限运⾏。本⽂介绍了 C# 程序如何设置来提⽰⽤户以管理员权限运⾏。
⾸先在项⽬中增加⼀个 Application Manifest File
默认的配置如下:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</asmv1:assembly>
我们可以看到这个配置中有⼀个 requestedExecutionLevel 项,这个项⽤于配置当前应⽤请求的执⾏权限级别。这个项有3个值可供选择,如下表所⽰:
Value Description Comment
asInvoker The application runs with the same access token as the
parent process.
Recommended for standard user applications. Do refractoring with
internal elevation points, as per the guidance provided earlier in this
document.
highestAvailable The application runs with the highest privileges the
current user can obtain.Recommended for mixed-mode applications. Plan to refractor the application in a future release.
requireAdministrator The application runs only for administrators and requires
that the application be launched with the full access
token of an administrator.
Recommended for administrator only applications. Internal
elevation points are not needed. The application is already running
elevated.
asInvoker : 如果选这个,应⽤程序就是以当前的权限运⾏。
highestAvailable: 这个是以当前⽤户可以获得的最⾼权限运⾏。
requireAdministrator: 这个是仅以系统管理员权限运⾏。
默认情况下是 asInvoker。
highestAvailable 和 requireAdministrator 这两个选项都可以提⽰⽤户获取系统管理员权限。那么这两个选项的区别在哪⾥呢?
他们的区别在于,如果我们不是以管理员帐号登录,那么如果应⽤程序设置为 requireAdministrator ,那么应⽤程序就直接运⾏失败,⽆法启动。⽽如果设置为 highestAvailable,则应⽤程序可以运⾏成功,但是是以当前帐号的权限运⾏⽽不是系统管理员权限运⾏。如果我们希望程序在⾮管理员帐号登录时也可以运⾏(这种情况下应该某些功能受限制) ,那么建议采⽤ highestAvailable 来配置。
关于requestedExecutionLevel 设置的权威⽂档请参考下⾯链接:
下⾯是修改后的配置⽂件:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</asmv1:assembly>
怎么设置文件夹权限
配置⽂件修改后,我们运⾏应⽤程序,就会⾸先弹出这样⼀个提⽰框,点 Yes 后,程序才可以继续运⾏,并且获得系统管理员的权限。
下⾯再来看看程序如何知道当前运⾏在系统管理员权限还是⾮系统管理员权限:
using System.Security.Principal
public static bool IsAdministrator()
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal =  new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
这段代码可以⽤于判断当前程序是否运⾏在系统管理员权限下。如果配置为 asInvoker,在win7 下,这个函数会返回 false ,如果是 requireAdministrator 则返回 true。
using System;
using System.Collections;
using System.IO;
using System.Security.AccessControl;
static class Tester
{
public static void Main()
{
try
{
string filename = @"f:\k"; //⽬标⽬录
string account = @"Administrator";//⽤户名
string userrights = @"RW";//权限字符串,⾃⼰定义的
AddDirectorySecurity(filename, account, userrights);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
static public void AddDirectorySecurity(string FileName, string Account, string UserRights)
{
FileSystemRights Rights = new FileSystemRights();
if (UserRights.IndexOf("R") >= 0)
{
Rights = Rights | FileSystemRights.Read;
}
if (UserRights.IndexOf("C") >= 0)
{
Rights = Rights | FileSystemRights.ChangePermissions;
}
if (UserRights.IndexOf("F") >= 0)
{
Rights = Rights | FileSystemRights.FullControl;
}
if (UserRights.IndexOf("W") >= 0)
{
Rights = Rights | FileSystemRights.Write;
}
}
bool ok;
DirectoryInfo dInfo = new DirectoryInfo(FileName);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
InheritanceFlags iFlags = new InheritanceFlags();
iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
FileSystemAccessRule AccessRule2 = new FileSystemAccessRule(Account, Rights, iFlags, PropagationFlags.None, AccessControlType.Allow);
dSecurity.ModifyAccessRule(AccessControlModification.Add, AccessRule2, out ok);
dInfo.SetAccessControl(dSecurity);
//列出⽬标⽬录所具有的权限
DirectorySecurity sec = Directory.GetAccessControl(FileName, AccessControlSections.All);
foreach (FileSystemAccessRule rule in sec.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))        {
Console.WriteLine("----------------------------------");
Console.WriteLine(rule.IdentityReference.Value);
if ((rule.FileSystemRights & FileSystemRights.Read) != 0)
Console.WriteLine(rule.FileSystemRights.ToString());
}
Console.Read();
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。