[轉] 訪問共享文件夾(解決輸入用戶名密碼問題)在.NET中的編程實現 --- 轉自: http://jackyxfl.blog.163.com/blog/static/164134150201110352115704/


 

摘要: 本文簡單介紹在.NET中如何 通過API實現局域網共享訪問編程
 
本頁內容
 
概述
一般用戶在訪問局域網中的計算機時都需要提供訪問憑據,如果想通過編程來實現自動登錄,.NET開發人員一般首先會想到通過調用WMI來實現。但是在實現過程中也許你會發現使用ConnectionOptions類不是很理想,因此本文采用了平台調用的方式來介紹共享訪問編程實現。
 
API 介紹
mpr.dll 是Windws操作系統網絡通訊相關模塊,通過對功能需求的分析,直接調用mpr.dll來實現該功能。在.NET中需要通過平台調用(platform invoke)來調用其中的方法,這里需要用到mpr.dll中的兩個方法。對於mpr.dll中包含的具體功能這里不進行闡述,大家通過MSDN可以找到詳細說明,這里只列出方法定義。
DWORD WNetAddConnection2(
  LPNETRESOURCE lpNetResource,
  LPCTSTR lpPassword,
  LPCTSTR lpUsername,
  DWORD dwFlags
);
 
該方法主要功能是添加遠程網絡連接。
參數描述如下:
lpNetResource :是一個包含網絡訪問資源的結構,在這里作為參數用來指定詳細的網絡連接信息,具體請看下面。
lpPassword :指出訪問遠程計算機的密碼。在Windows 95/98/Me 系統中,該值必須設置為NULL或空字符串。
lpUsername :指出訪問遠程計算機的用戶名。在Windows 95/98/Me 系統中,該值必須設置為NULL或空字符串。
dwFlags :指出連接選項,包含六種設置,具體可以看MSDN。
 
方法返回值:如果方法執行成功返回“NO_ERROR”即“0”。如果執行失敗返回 System Error Code
 
NETRESOURCE 結構通過多個字段指定網絡連接資源信息。定義如下:
typedef struct _NETRESOURCE {
  DWORD dwScope;
  DWORD dwType;
  DWORD dwDisplayType;
  DWORD dwUsage;
  LPTSTR lpLocalName;
  LPTSTR lpRemoteName;
  LPTSTR lpComment;
  LPTSTR lpProvider;
} NETRESOURCE;
 
各個成員描述如下:
dwScope :指定枚舉范圍。設置RESOURCE_CONNECTED,RESOURCE_GLOBALNET,RESOURCE_REMEMBERED三值之一。
dwType :指定訪問的資源類型。設置三個值之一。RESOURCETYPE_ANY表示所有資源;RESOURCETYPE_DISK表示磁盤資源;RESOURCETYPE_PRINT表示打印機。
dwDisplayType :指出資源顯示類型。RESOURCEDISPLAYTYPE_DOMAIN;RESOURCEDISPLAYTYPE_SERVER;RESOURCEDISPLAYTYPE_SHARE;RESOURCEDISPLAYTYPE_GENERIC。
dwUsage :描述資源的使用方式。設置RESOURCEUSAGE_CONNECTABLE 或RESOURCEUSAGE_CONTAINER。
lpLocalName :同dwScope關聯,指定本地映射。
lpRemoteName :遠程訪問文件夾路徑。
lpComment :描述。
lpProvider :資源提供者,可以設置為NULL。
 
DWORD WNetCancelConnection2(
  LPCTSTR lpName,
  DWORD dwFlags,
  BOOL fForce
);
 
通過該方法實現釋放存在的網絡連接。
各成員描述如下:
lpName :指定本地驅動器或遠程共享資源
dwFlags :表示斷開連接方式。設置 0 或CONNECT_UPDATE_PROFILE。
fForce :如果當前正在使用遠程資源,是否進行強制斷開連接。如果設置FALSE,在有遠程資源使用的情況下關閉連接操作將會失敗。
 
方法返回值:如果方法執行成功返回“NO_ERROR”即“0”。如果執行失敗返回 System Error Code
 
針對以上兩個方法,有些System Error Code返回值並不意味遠程資源不可以訪問。
例如:
ERROR_SESSION_CREDENTIAL_CONFLICT
1219
Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.
ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
1220
An attempt was made to establish a session to a network server, but there are already too many sessions established to that server.
 
代碼實現
為便於在.NET環境中使用,本文寫了一個WNetConnectionHelper靜態類,對這些方法進行包裝。
P/Invoke 需要引用 System.Runtime.InteropServices 命名空間。 由於代碼簡短,下面給出完整實現代碼。
public  static class WNetConnectionHelper
{
    [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")]
    private static extern uint WNetAddConnection2(NetResource lpNetResource, string lpPassword, string lpUsername, uint dwFlags);
 
    [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2"))]
    private static extern uint WNetCancelConnection2(string lpName, uint dwFlags, bool fForce);
 
    [StructLayout(LayoutKind.Sequential)]
    public class NetResource
    {
        public int dwScope;
        public int dwType;
        public int dwDisplayType;
        public int dwUsage;
        public string lpLocalName;
        public string lpRemoteName;
        public string lpComment;
        public string lpProvider;
    }
 
    public static uint WNetAddConnection(NetResource netResource,string username,string password)
    {
        uint result = WNetAddConnection2(netResource, password, username, 0);
        return result;
    }
 
    public static uint WNetAddConnection(string username, string password, string remoteName, string localName)
    {
        NetResource netResource = new NetResource();
        netResource.dwScope = 2;       //RESOURCE_GLOBALNET
        netResource.dwType = 1;       //RESOURCETYPE_ANY
        netResource.dwDisplayType = 3; //RESOURCEDISPLAYTYPE_GENERIC
        netResource.dwUsage = 1;       //RESOURCEUSAGE_CONNECTABLE
        netResource.lpLocalName = localName;
        netResource.lpRemoteName = remoteName.TrimEnd('//');
        //netResource.lpRemoteName = lpComment;
        //netResource.lpProvider = null;
        uint result = WNetAddConnection2(netResource, password, username, 0);
        return result;
    }
 
    public static uint WNetCancelConnection(string name,uint flags,bool force)
    {
        uint nret = WNetCancelConnection2(name, flags, force);
        return nret;
    }
}
 
應用示例
最后,通過兩個簡單示例來演示 WNetConnectionHelper 類的使用
a .列舉遠程計算機共享文件夾資源。代碼如下:
try
{
    string  result = WNetConnectionHelper.WNetAddConnection("192.120.40.10//ShareUser""xxxxxx"@"//192.120.40.10/test"null);
    string  [] files = Directory.GetFiles(@"//192.120.40.56/test/fw");
    string  s1 = GetFile(@"//192.120.40.10/test/fw/test.doc");
    uint  n =   WNetConnectionHelper.WNetCancelConnection("//192.120.40.10//test", 1, true);
}
catch  (Exception ex)
{
    // 編寫異常處理代碼
}
 
 
b. 另一個比較常見的應用是在ASP.NET服務器端訪問其他計算機的資源,比如文檔服務器,然后通過Web頁面輸出。
主要示例代碼如下:
protected  void Page_Load(object sender, EventArgs e)
{
    uint r = WNetConnectionHelper.WNetAddConnection("192.120.40.10//username""password"@"//192.120.40.10/test""Z:");
    string filename = @"//192.120.40.10/test/fw/1.doc";
    ReadFile(filename);
}
 
寫文件到Web輸出:
public  void ReadFile(string filename)
{
    Response.Clear();
    Response.Charset = "utf-8";
    Response.Buffer = true;
    this.EnableViewState = false;
    Response.ContentType = "application/ms-word";
    Response.ContentEncoding = System.Text.Encoding.UTF8;
    Response.AppendHeader("Content-Disposition""inline;filename=1.doc");
    try
    {
         Response.WriteFile(filename, true);
    }
    catch (Exception ex)
    {
        Response.Write(ex.ToString());
    }
    Response.Flush();
}
以上方法對於大文件使用Response.WriteFile方法會有些問題,在實際編程中需要做優化處理。
 
結束語

本文中的有些功能描述可能不夠具體或妥當,如果需要了解mpr.dll的更多功能還是建議看MSDN文檔。對於WNetConnectionHelper的實現存在一些需要完善的地方,不過對於一般的應用基本可以滿足,在實際使用時還需要考慮多線程的情況。另外,在有同名驅動器映射的情況下需要做一些判斷,而且弄清楚System Error Code的含義對代碼的調試及正確執行有很大的幫助。This is some sample text. You are usingFCKeditor.

第二種方法是通過:cmd->net use 輸入一次用戶名和密碼后,客戶端訪問共享文件就不用再輸入密碼  命令:“net use \\192.168.39.178 "admin" /user:"admin"”
using   System.Diagnostics;   


Process   prc   =   new   Process(); 
                        prc.StartInfo.FileName   =   @ "cmd.exe "; 
                        prc.StartInfo.UseShellExecute   =   false; 
                        prc.StartInfo.RedirectStandardInput   =   true; 
                        prc.StartInfo.RedirectStandardOutput   =   true; 
                        prc.StartInfo.RedirectStandardError   =   true; 
                        prc.StartInfo.CreateNoWindow   =   false; 

                        prc.Start(); 
                        string   cmd   =   @ "net   use   z:   \\192.168.1.1\tmp   ""pass""   /user:""name"""; 
                        //"pass"連接服務器的密碼   user:"name"用戶名
                 // Process.Start( "net ",@ "use   z:   \\192.168.1.1\tmp   " "pass " "   /user: " "name " " ");
                        prc.StandardInput.WriteLine(cmd); 

                        prc.StandardInput.Close(); 


免責聲明!

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



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