asp.net 操作共享目錄

1.建立訪問類

View Code
    /// <summary>
    /// 用戶訪問共享類
    /// </summary>
    public class WNetHelper
    {

    #region ==  enums  ==
        public enum RESOURCE_SCOPE
        {
            RESOURCE_CONNECTED = 0x00000001,
            RESOURCE_GLOBALNET = 0x00000002,
            RESOURCE_REMEMBERED = 0x00000003,
            RESOURCE_RECENT = 0x00000004,
            RESOURCE_CONTEXT = 0x00000005
        }

        public enum RESOURCE_TYPE
        {
            RESOURCETYPE_ANY = 0x00000000,
            RESOURCETYPE_DISK = 0x00000001,
            RESOURCETYPE_PRINT = 0x00000002,
            RESOURCETYPE_RESERVED = 0x00000008,
        }

        public enum RESOURCE_USAGE
        {
            RESOURCEUSAGE_CONNECTABLE = 0x00000001,
            RESOURCEUSAGE_CONTAINER = 0x00000002,
            RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
            RESOURCEUSAGE_SIBLING = 0x00000008,
            RESOURCEUSAGE_ATTACHED = 0x00000010,
            RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),
        }

        public enum RESOURCE_DISPLAYTYPE
        {
            RESOURCEDISPLAYTYPE_GENERIC = 0x00000000,
            RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001,
            RESOURCEDISPLAYTYPE_SERVER = 0x00000002,

            RESOURCEDISPLAYTYPE_SHARE = 0x00000003,
            RESOURCEDISPLAYTYPE_FILE = 0x00000004,
            RESOURCEDISPLAYTYPE_GROUP = 0x00000005,
            RESOURCEDISPLAYTYPE_NETWORK = 0x00000006,
            RESOURCEDISPLAYTYPE_ROOT = 0x00000007,
            RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008,
            RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009,
            RESOURCEDISPLAYTYPE_TREE = 0x0000000A,
            RESOURCEDISPLAYTYPE_NDSCONTAINER = 0x0000000B
        }

        public struct NETRESOURCE
        {
            public RESOURCE_SCOPE dwScope;
            public RESOURCE_TYPE dwType;
            public RESOURCE_DISPLAYTYPE dwDisplayType;
            public RESOURCE_USAGE dwUsage;
            //[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]
            public string lpLocalName;
            //[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]
            public string lpRemoteName;
            //[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]
            public string lpComment;
            //[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]
            public string lpProvider;
        }
        #endregion

    [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")]  
    private static extern uint WNetAddConnection2(ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, uint dwFlags);  
  
    [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")]  
    private static extern uint WNetCancelConnection2(string lpName, uint dwFlags, bool fForce);  
  
  
    /// <summary>  
    /// 为网络共享做本地映射  
   /// </summary>  
    /// <param name="username">访问用户名(windows系统需要加计算机名,如:comp-1/user-1)</param>  
    /// <param name="password">访问用户密码</param>  
    /// <param name="remoteName">网络共享路径(如://192.168.0.9/share)</param>  
    /// <param name="localName">本地映射盘符</param>  
    /// <returns></returns>  
    public static uint WNetAddConnection(string username, string password, string remoteName, string localName)  
    {  
        NETRESOURCE netResource;

        netResource.dwScope = RESOURCE_SCOPE.RESOURCE_GLOBALNET;
        netResource.dwType = RESOURCE_TYPE.RESOURCETYPE_ANY;
        netResource.dwUsage = RESOURCE_USAGE.RESOURCEUSAGE_CONNECTABLE;
        netResource.dwDisplayType = RESOURCE_DISPLAYTYPE.RESOURCEDISPLAYTYPE_SHARE;
        netResource.lpLocalName = localName;
        netResource.lpRemoteName = remoteName;
        netResource.lpProvider = null;
        netResource.lpComment = string.Empty;
        uint result = WNetAddConnection2(ref netResource, password, username, 1);  
  
        return result;  
    }  
  
    public static uint WNetCancelConnection(string name, uint flags, bool force)  
    {  
        uint nret = WNetCancelConnection2(name, flags, force);  
  
        return nret;  
    }

    public static bool CreateDirectory(string path, string username, string password, string remoteName, string localName)
    {
        //更換用戶,這裡的用戶名 username=“計算機名/用戶名”
        //LogonImpersonate imper = new LogonImpersonate(username, password);
        uint state = 0;
        if (!Directory.Exists(localName))
        {
            state = WNetHelper.WNetAddConnection(username, password, remoteName, localName);
        }
        if (state.Equals(0))
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            return true;
        }
        else
        {
            throw new Exception("添加网络驱动器错误,错误号:" + state.ToString());
        }
    } 
    }

2.建立模擬帳戶類,如果用web.config配置,則不需要下面的類

View Code
    /// <summary>
    /// 更換iis模擬帳戶
    /// </summary>
    public class LogonImpersonate
    {
        static public string DefaultDomain  
        {  
            get  
            {  
                return ".";  
            }  
        }  
  
    const int LOGON32_LOGON_INTERACTIVE = 2;  
    const int LOGON32_PROVIDER_DEFAULT = 0;  
  
    [System.Runtime.InteropServices.DllImport("Kernel32.dll")]  
    extern static int FormatMessage(int flag, ref   IntPtr source, int msgid, int langid, ref   string buf, int size, ref   IntPtr args);  
  
    [System.Runtime.InteropServices.DllImport("Kernel32.dll")]  
    extern static bool CloseHandle(IntPtr handle);  
  
    [System.Runtime.InteropServices.DllImport("Advapi32.dll", SetLastError = true)]  
    extern static bool LogonUser(  
    string lpszUsername,  
    string lpszDomain,  
    string lpszPassword,  
    int dwLogonType,  
    int dwLogonProvider,  
    ref   IntPtr phToken  
    );  
  
    IntPtr token;  
    System.Security.Principal.WindowsImpersonationContext context;  
  
    public LogonImpersonate(string username, string password)  
    {  
        if (username.IndexOf("//") == -1)  
        {  
            Init(username, password, DefaultDomain);  
        }  
        else  
        {  
            string[] pair = username.Split(new string[]{"//"},2,StringSplitOptions.None);  
            Init(pair[1], password, pair[0]);  
        }  
    }  
    public LogonImpersonate(string username, string password, string domain)  
    {  
        Init(username, password, domain);  
    }  
    void Init(string username, string password, string domain)  
    {  
        if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref   token))  
        {  
            bool error = true;  
            try  
            {  
                context = System.Security.Principal.WindowsIdentity.Impersonate(token);  
                error = false;  
            }  
            finally  
            {  
                if (error)  
                    CloseHandle(token);  
            }  
        }  
        else  
        {  
            int err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();  
  
            IntPtr tempptr = IntPtr.Zero;  
            string msg = null;  
  
            FormatMessage(0x1300, ref   tempptr, err, 0, ref   msg, 255, ref   tempptr);  
  
            throw (new Exception(msg));  
        }  
    }  
    ~LogonImpersonate()  
    {  
        Dispose();  
    }  
    public void Dispose()  
    {  
        if (context != null)  
        {  
            try  
            {  
                context.Undo();  
            }  
            finally  
            {  
                CloseHandle(token);  
                context = null;  
            }  
        }  
    } 
    }

3.使用配置文件,如下配置:

登陸信息:

  <appSettings>
    <add key="RemoteUID" value="administrator"/>
    <add key="RemotePWD" value="administrator"/>
    <add key="LogicDriver" value="W:"/>
    <add key="SAPTXTDir" value="\\10.101.1.72\SAPOUTPUT"/>
  </appSettings>

模擬帳戶:

    <!--啟用動態模擬-->
    <identity impersonate="true" userName="administrator" password="administrator" />

在模擬帳號中,我們使用了明碼,也許你認為不好,那麼可以存儲在註冊表中。那麼會配置成如下形式:

<identity impersonate="true" userName="registry:HKEY_LOCAL_MACHINESYSTEMaspnetidASPNET_SETREG,userName" password="registry:HKEY_LOCAL_MACHINESYSTEMaspnetidASPNET_SETREG,password"/>

要實現從註冊表讀取,那麼除了要在web.config中進行配置外,需要在註冊表中寫入信息。下面的操作將達到這個目的:

运行Aspnet_setreg.exe
示例命令如下:aspnet_setreg -k:SYSTEMaspnetid -u:"用戶名" -p:"密碼"

Aspnet_setreg.exe工具可以從微軟網站上下載。

4.程序中調用:

    string RemoteUID=   System.Web.Configuration.WebConfigurationManager.AppSettings["RemoteUID"].ToString();
           string RemotePWD =  System.Web.Configuration.WebConfigurationManager.AppSettings["RemotePWD"].ToString();
           string LogicDriver= System.Web.Configuration.WebConfigurationManager.AppSettings["LogicDriver"].ToString();
           string SAPTXTDir=    System.Web.Configuration.WebConfigurationManager.AppSettings["SAPTXTDir"].ToString();
           WNetHelper.CreateDirectory(SAPTXTDir+"//M", RemoteUID, RemotePWD, SAPTXTDir, LogicDriver);

5.模式是使用web.config中的模擬帳戶進行操作的。如果不使用web.config,請在操作之前,執行下面的語句,以更換iis的帳號

 //更換用戶,這裡的用戶名 username=“計算機名/用戶名”
        //LogonImpersonate imper = new LogonImpersonate(username, password);

6.代碼中使用 模擬帳號,可以用前面的類,也可以直接用代碼:

View Code
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;

WindowsImpersonationContext impersonationContext; 

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

public void Page_Load(Object s, EventArgs e)
{
   if(impersonateValidUser("username", "domain", "password"))
   {
      //Insert your code that runs under the security context of a specific user here.
      undoImpersonation();
   }
   else
   {
      //Your impersonation failed. Therefore, include a fail-safe mechanism here.
   }
}

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

   if(LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 
   LOGON32_PROVIDER_DEFAULT, ref token) != 0)
   {
      if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
      {
         tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
         impersonationContext = tempWindowsIdentity.Impersonate();
         if (impersonationContext != null)
            return true;
         else
            return false; 
      }
      else
         return false;
   } 
   else
      return false;
}
private void undoImpersonation()
{
     impersonationContext.Undo();
} 

 

posted @ 2012-04-24 13:54  無限遐想  阅读(2186)  评论(2编辑  收藏  举报