Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
390 views
Welcome To Ask or Share your Answers For Others

1 Answer

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 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);
    }
}

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";
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...