C#使用管理员帐户凭据访问本地文件夹

时间:2015-05-12 07:26:25

标签: c# permissions directory

我的计算机中有两个用户帐户

用户1(普通用户)

管理

现在我有文件夹" e:\ Folder1 "仅限管理员帐户具有完全访问权限。用户!无法访问该文件夹。

我有一个WPF应用程序,它只能在用户1 帐户中运行。我希望用户1使用wpf应用程序访问" Folder1 "。

我想知道如何使用C#来做到这一点。

我尝试了以下它无法正常工作。

NetworkCredential theNetworkCredential = new NetworkCredential(@"admin", "pass");
            CredentialCache theNetCache = new CredentialCache();
            theNetCache.Add(new Uri(@"E:\SDAVideo"), "Basic", theNetworkCredential);
            string[] theFolders = Directory.GetDirectories(@"E:\SDAVideo");

这是我尝试过的。 使用以下代码,我可以获得Windows身份管理用户帐户

SafeTokenHandle safeTokenHandle;
        try
        {
            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token. 
            const int LOGON32_LOGON_INTERACTIVE = 2;

            // Call LogonUser to obtain a handle to an access token. 
            bool returnValue = LogonUser("admin", "", "pass",
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);
            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Debug.Write("\nLogonUser failed with error code : " + ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }
            using (safeTokenHandle)
            {
                Debug.Write("\nDid LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
                Debug.Write("\nValue of Windows NT token: " + safeTokenHandle);

                // Check the identity.
                Debug.Write("\nBefore impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
                Debug.Write("\nWriteAccess before: " + DirectoryHasPermission(@"E:\SDAVideo", WindowsIdentity.GetCurrent(), FileSystemRights.Write));
                // Use the token handle returned by LogonUser. 
                using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
                {

                    // Check the identity.
                    Debug.Write("\nAfter impersonation: "
                        + WindowsIdentity.GetCurrent().Name);
                    AccessFolder(WindowsIdentity.GetCurrent(), @"E:\SDAVideo");
                    //Debug.Write("\nWriteAccess after: " + DirectoryHasPermission(@"E:\SDAVideo", WindowsIdentity.GetCurrent(), FileSystemRights.Write));
                }
                // Releasing the context object stops the impersonation 
                // Check the identity.
                Debug.Write("\nAfter closing the context: " + WindowsIdentity.GetCurrent().Name);

            }

        }
        catch (Exception ex)
        {
            Debug.Write("\n1" + ex.ToString());
        }

public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private SafeTokenHandle()
            : base(true)
        {
        }

        [DllImport("kernel32.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr handle);

        protected override bool ReleaseHandle()
        {
            return CloseHandle(handle);
        }
    }
public static bool DirectoryHasPermission(string DirectoryPath,  WindowsIdentity identity, FileSystemRights AccessRight)
    {
        //if (string.IsNullOrEmpty(DirectoryPath)) return false;

        try
        {
            AuthorizationRuleCollection rules = Directory.GetAccessControl(DirectoryPath).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
            //WindowsIdentity identity = WindowsIdentity.GetCurrent();
            Debug.Write("\nUSER: " + identity.Name);
            foreach (FileSystemAccessRule rule in rules)
            {
                if (identity.Groups.Contains(rule.IdentityReference))
                {
                    if ((AccessRight & rule.FileSystemRights) == AccessRight)
                    {
                        if (rule.AccessControlType == AccessControlType.Allow)
                            return true;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Debug.Write("\n2 " + ex.ToString());
        }
        return false;
    }
public static void AccessFolder(WindowsIdentity identity, string DirectoryPath)
    {
        try
        {
            Debug.Write("\nUSER: " + identity.Name);
            DirectoryInfo myDirectoryInfo = new DirectoryInfo(DirectoryPath);
            DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();

            myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(identity.Name, FileSystemRights.Write, AccessControlType.Allow));

            myDirectoryInfo.SetAccessControl(myDirectorySecurity);
            string pathString = System.IO.Path.Combine(DirectoryPath, "test.txt");
            if (!System.IO.File.Exists(pathString))
            {
                using (System.IO.FileStream fs = System.IO.File.Create(pathString))
                {
                    for (byte i = 0; i < 100; i++)
                    {
                        fs.WriteByte(i);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Debug.Write("\n3 " + ex.ToString());
        }
    }

错误我得到如下 System.UnauthorizedAccessException:尝试执行未经授权的操作。

System.InvalidOperationException:方法失败,出现意外错误代码1346。

所有这些都失败了,我唯一能做的就是成功获得管理员用户的Windows身份。 现在,我需要解决这两个问题 1.如何使用管理员的Windows身份检查应用是否具有写入权限 2.如果是,如何在文件夹中写入内容。

1 个答案:

答案 0 :(得分:0)

试试:

using System;
using System.IO;
using System.Security.AccessControl;

namespace MyWpfApplication
{
    public class AccessRules
    {
        private void SetAccessRuleForCurrentUser()
        {
            DirectoryInfo myDirectoryInfo = new DirectoryInfo(@"e:\Folder1");
            DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();

            myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(System.Security.Principal.WindowsIdentity.GetCurrent().Name, FileSystemRights.Read, AccessControlType.Allow));

            myDirectoryInfo.SetAccessControl(myDirectorySecurity);
        }
    }
}