c#編寫的服務中訪問網絡位置的共享文件夾


使用LocalSystem運行的服務不能訪問共享文件夾,即使共享文件夾權限是對“EveryOne”可讀寫也不行,目前使用過兩種方式,但都需要設置用戶密碼。

1、使用用戶名加密碼的方式運行服務。

將 ProjectInstaller 的 Account設置為User

然后打開 ProjectInstaller 的設計器代碼

 

 

 在 InitializeComponent 中設置 ProjectInstaller的Username和Password。運行服務時會直接以設置的用戶名運行,可以直接訪問該用戶名可訪問的所有位置。

 

2、通過API模擬用戶登錄,感覺比較靈活,可以在服務中隨時切換到不同用戶權限,服務的運行權限為LocalSystem。

public static class LogonNet
    {
        const int LOGON32_LOGON_INTERACTIVE = 2;
        const int LOGON32_LOGON_NETWORK = 3;
        const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
        
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_PROVIDER_WINNT50 = 3;
        const int LOGON32_PROVIDER_WINNT40 = 2;
        const int LOGON32_PROVIDER_WINNT35 = 1;

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int LogonUser(String lpszUserName,
            String lpszDomain,
            String lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int DuplicateToken(IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool RevertToSelf();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        private static WindowsImpersonationContext impersonationContext;

        public static bool impersonateValidUser(String userName, String domain, String password)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            if (RevertToSelf())
            {
                if (LogonUser(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS,
                    LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        impersonationContext = tempWindowsIdentity.Impersonate();
                        if (impersonationContext != null)
                        {
                            System.AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
                            IPrincipal pr = System.Threading.Thread.CurrentPrincipal;
                            IIdentity id = pr.Identity;
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }
                }
            }

            if (token != IntPtr.Zero)
                CloseHandle(token);

            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);

            return false;
        }
        public static void undoImpersonation()
        {
            impersonationContext.Undo();
        }
    }

 調用方式

private void test()
        {
            if (LogonNet.impersonateValidUser("userTest", "Users", "userPassword"))
            {
                using (StreamWriter writer=new StreamWriter("\\192.168.1.13\\ShareTest\\test.txt"))
                {
                    writer.WriteLine("模擬登錄訪問網絡共享文件成功");
                }
            }
        }

 感覺第二種方式更靈活一點,先這樣用了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM