问题描述
我在尝试列出我的 PC 上的某些文件夹时遇到拒绝访问"异常,例如c:Documents and Settings".我的应用程序从管理员帐户运行并具有提升的权限 (<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
)
I'm getting an "Access denied" exception when trying to list some folders on my PC, such as 'c:Documents and Settings'. My application is running from an administrator account and with elevated privileges (<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
)
我还需要做什么才能访问这些文件夹?
What else I need to do to access such folders?
推荐答案
需要以管理员身份运行,但还不够,还需要启用 Backup 权限,此处隐含记录:连接点
Running as administrator is necessary, but not enough, you also need to enable the Backup privilege, as implicitely documented here: Junction Points
%SystemDrive%Documents and Settings 目录现在存储在 %SystemDrive%Users 目录中[...] 备份应用程序必须能够备份和恢复连接点.
%SystemDrive%Documents and Settings directory is now stored in the %SystemDrive%Users directory [...] Backup applications must be capable of backing up and restoring junction points.
所以这是一个有效的例子:
So here is an example that works:
using (Privilege p = new Privilege(Privilege.Backup))
{
foreach (string path in Directory.GetFileSystemEntries(@"c:documents and settings"))
{
Console.WriteLine(path);
}
}
请注意,据我所知,没有公共 .NET 类可以通过编程方式启用特权,但我使用瘦包装器公开了 System.Security.AccessControl (mscorlib) 中的一个内部类.它基于完全公开的 Windows AdjustTokenPrivileges 函数.
Note there is no public .NET class to enable privilege programmatically to my knowledge, but there is one internal in System.Security.AccessControl (mscorlib) that I have exposed using a thin wrapper. It's based on the fully public Windows AdjustTokenPrivileges function.
/// <summary>
/// Defines a Windows privilege.
/// </summary>
public sealed class Privilege : IDisposable
{
private static Type _privilegeType;
private object _privilege;
static Privilege()
{
_privilegeType = typeof(string).Assembly.GetType("System.Security.AccessControl.Privilege", false); // mscorlib
}
/// <summary>
/// Initializes a new instance of the <see cref="Privilege"/> class and enable the privilege.
/// </summary>
/// <param name="name">The privilege name.</param>
public Privilege(string name)
: this(name, true)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Privilege" /> class.
/// </summary>
/// <param name="name">The privilege name.</param>
/// <param name="enable">if set to <c>true</c> the privilege is enabled.</param>
public Privilege(string name, bool enable)
{
if (name == null)
throw new ArgumentNullException("name");
if (_privilegeType == null)
throw new NotSupportedException();
_privilege = _privilegeType.GetConstructors()[0].Invoke(new object[] { name });
if (enable)
{
Enable();
}
}
/// <summary>
/// Disable this privilege from the current thread.
/// </summary>
public void Revert()
{
_privilegeType.InvokeMember("Revert", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, _privilege, null);
}
/// <summary>
/// Gets a value indicating whether Revert must be called.
/// </summary>
/// <value>
/// <c>true</c> if Revert must be called; otherwise, <c>false</c>.
/// </value>
public bool NeedToRevert
{
get
{
return (bool)_privilegeType.InvokeMember("NeedToRevert", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, _privilege, null);
}
}
/// <summary>
/// Enables this privilege to the current thread.
/// </summary>
public void Enable()
{
_privilegeType.InvokeMember("Enable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, _privilege, null);
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (NeedToRevert)
{
Revert();
}
}
/// <summary>
/// The SE_ASSIGNPRIMARYTOKEN_NAME privilege.
/// </summary>
public const string AssignPrimaryToken = "SeAssignPrimaryTokenPrivilege";
/// <summary>
/// The SE_AUDIT_NAME privilege.
/// </summary>
public const string Audit = "SeAuditPrivilege";
/// <summary>
/// The SE_BACKUP_NAME privilege.
/// </summary>
public const string Backup = "SeBackupPrivilege";
/// <summary>
/// The SE_CHANGE_NOTIFY_NAME privilege.
/// </summary>
public const string ChangeNotify = "SeChangeNotifyPrivilege";
/// <summary>
/// The SE_CREATE_GLOBAL_NAME privilege.
/// </summary>
public const string CreateGlobal = "SeCreateGlobalPrivilege";
/// <summary>
/// The SE_CREATE_PAGEFILE_NAME privilege.
/// </summary>
public const string CreatePageFile = "SeCreatePagefilePrivilege";
/// <summary>
/// The SE_CREATE_PERMANENT_NAME privilege.
/// </summary>
public const string CreatePermanent = "SeCreatePermanentPrivilege";
/// <summary>
/// The SE_CREATE_SYMBOLIC_LINK_NAME privilege.
/// </summary>
public const string CreateSymbolicLink = "SeCreateSymbolicLinkPrivilege";
/// <summary>
/// The SE_CREATE_TOKEN_NAME privilege.
/// </summary>
public const string CreateToken = "SeCreateTokenPrivilege";
/// <summary>
/// The SE_DEBUG_NAME privilege.
/// </summary>
public const string Debug = "SeDebugPrivilege";
/// <summary>
/// The SE_ENABLE_DELEGATION_NAME privilege.
/// </summary>
public const string EnableDelegation = "SeEnableDelegationPrivilege";
/// <summary>
/// The SE_IMPERSONATE_NAME privilege.
/// </summary>
public const string Impersonate = "SeImpersonatePrivilege";
/// <summary>
/// The SE_INC_BASE_PRIORITY_NAME privilege.
/// </summary>
public const string IncreaseBasePriority = "SeIncreaseBasePriorityPrivilege";
/// <summary>
/// The SE_INCREASE_QUOTA_NAME privilege.
/// </summary>
public const string IncreaseQuota = "SeIncreaseQuotaPrivilege";
/// <summary>
/// The SE_INC_WORKING_SET_NAME privilege.
/// </summary>
public const string IncreaseWorkingSet = "SeIncreaseWorkingSetPrivilege";
/// <summary>
/// The SE_LOAD_DRIVER_NAME privilege.
/// </summary>
public const string LoadDriver = "SeLoadDriverPrivilege";
/// <summary>
/// The SE_LOCK_MEMORY_NAME privilege.
/// </summary>
public const string LockMemory = "SeLockMemoryPrivilege";
/// <summary>
/// The SE_MACHINE_ACCOUNT_NAME privilege.
/// </summary>
public const string MachineAccount = "SeMachineAccountPrivilege";
/// <summary>
/// The SE_MANAGE_VOLUME_NAME privilege.
/// </summary>
public const string ManageVolume = "SeManageVolumePrivilege";
/// <summary>
/// The SE_PROF_SINGLE_PROCESS_NAME privilege.
/// </summary>
public const string ProfileSingleProcess = "SeProfileSingleProcessPrivilege";
/// <summary>
/// The SE_RELABEL_NAME privilege.
/// </summary>
public const string Relabel = "SeRelabelPrivilege";
/// <summary>
/// The SE_REMOTE_SHUTDOWN_NAME privilege.
/// </summary>
public const string RemoteShutdown = "SeRemoteShutdownPrivilege";
///// <summary>
///// The SE_RESERVE_PROCESSOR_NAME privilege.
///// </summary>
//public const string ReserveProcessor = "SeReserveProcessorPrivilege";
/// <summary>
/// The SE_RESTORE_NAME privilege.
/// </summary>
public const string Restore = "SeRestorePrivilege";
/// <summary>
/// The SE_SECURITY_NAME privilege.
/// </summary>
public const string Security = "SeSecurityPrivilege";
/// <summary>
/// The SE_SHUTDOWN_NAME privilege.
/// </summary>
public const string Shutdown = "SeShutdownPrivilege";
/// <summary>
/// The SE_SYNC_AGENT_NAME privilege.
/// </summary>
public const string SyncAgent = "SeSyncAgentPrivilege";
/// <summary>
/// The SE_SYSTEM_ENVIRONMENT_NAME privilege.
/// </summary>
public const string SystemEnvironment = "SeSystemEnvironmentPrivilege";
/// <summary>
/// The SE_SYSTEM_PROFILE_NAME privilege.
/// </summary>
public const string SystemProfile = "SeSystemProfilePrivilege";
/// <summary>
/// The SE_SYSTEMTIME_NAME privilege.
/// </summary>
public const string SystemTime = "SeSystemtimePrivilege";
/// <summary>
/// The SE_TAKE_OWNERSHIP_NAME privilege.
/// </summary>
public const string TakeOwnership = "SeTakeOwnershipPrivilege";
/// <summary>
/// The SE_TCB_NAME privilege.
/// </summary>
public const string TrustedComputingBase = "SeTcbPrivilege";
/// <summary>
/// The SE_TIME_ZONE_NAME privilege.
/// </summary>
public const string TimeZone = "SeTimeZonePrivilege";
/// <summary>
/// The SE_TRUSTED_CREDMAN_ACCESS_NAME privilege.
/// </summary>
public const string TrustedCredentialManagerAccess = "SeTrustedCredManAccessPrivilege";
/// <summary>
/// The SE_UNDOCK_NAME privilege.
/// </summary>
public const string Undock = "SeUndockPrivilege";
/// <summary>
/// The SE_UNSOLICITED_INPUT_NAME privilege.
/// </summary>
public const string UnsolicitedInput = "SeUnsolicitedInputPrivilege";
}
这篇关于无法列出某些文件夹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!