点击超链接从VSTF、SVN及文件共享服务器上下载文件
最近实现一个公司的需求, 不同部门的产品文档路径放在不同地址、不同种类的服务器上, 草草做完一版, 发现文档路径中还有文件共享路径(\\192.168.0.0类型)、还有svn(http://192.168.0.0类型)、还有VSTF路径($/Document/ss....), 各种坑啊, 领导们说起来都很轻松哈, 这样那样就行..... 这个应该不难吧.... 都懒得跟他们解释, 爱咋咋吧
言归正传, 文档路径是放在不同类型的服务器上, 目标是一点击文档的链接就能直接下载文件, 还是所有的人都可以下载, 还不能影响用户的原有权限.开始想的简单了, 后来发现这东西头疼啊.
思路:
对于VSTF文件: 当点击的时候文档连接的时候, 通过VSTF的提供的工具, 将代码及Sql脚本获取到固定地址的文件夹, 该文件夹需要发布为网站且能够通过浏览器直接访问文件.
对于SVN文件: 可以通过HTTP访问, 但是涉及到权限问题, 需要给请求附加临时的账户信息, 这里没有考虑修改Cookie信息, 这会是用户的权限变成临时账户. 实现方法就是由WebServer发起请求, 附加账户信息, 将获得的信息返回给客户端浏览器.
对于文件共享: 为了达到练习的效果, 使用了WMI方式和CMD.exe两种方式.
总体思路: 就是返回给客户端的超链接为xxx.com/WebRequestHandler?url=http://192.168.0.0.xxx, 一般处理程序接收到请求后, 更具请求类型、地址类型做相应处理.
领导催促的比较急, 所以好多地方都直接偷懒了, 没有封装, 想的是下回搞TD的时候在整理下吧
具体代码如下:
页面中的超链接代码:
lnkDocPath.Text = Common.StringChange.HtmlSignChange(txtDocPath.Text = info.DocPath); lnkDocPath.NavigateUrl = string.Format("http://{0}/common/WebRequestTransferHandler.ashx?url={1}", Request.Url.Authority, Server.UrlEncode(lnkDocPath.Text.Trim()));
//请求转发器代码, WebRequestTransferHandler.ashx
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Net; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Reflection; using System.Management; using System.Web.UI; namespace WebSite.Common { /// <summary> /// 透明的跨站访问处理器 /// </summary> public class WebRequestTransferHandler : IHttpHandler, System.Web.SessionState.IRequiresSessionState { private static readonly string[] _allowFileType = new string[] { "*.doc", "*.docx", "*.xls", "*.xlsx", "*.ppt", "*.pptx","*.sql","*.txt","*.gz", "*.rtf" }; public void ProcessRequest(HttpContext context) { context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.ContentType = "text/plain"; if (!string.IsNullOrEmpty(context.Request.Url.PathAndQuery) && context.Request.Url.PathAndQuery.StartsWith("/common/WebRequestTransferHandler.ashx?url=")) { string newUrl = context.Request.RawUrl.Trim().Replace(" ", "%20").Replace("/common/WebRequestTransferHandler.ashx?url=", ""); //处理请求地址 DocumentFileType docType = FileHelper.GetTransferedUrl(context, ref newUrl); if (docType != DocumentFileType.SharedDir) { HttpWebRequest hwrRequest = HttpWebRequest.Create(newUrl) as HttpWebRequest; //添加请求头, 其中Accept、Content-Length、Content-Type、User-Agent只能通过如下方式设置 foreach (string str in context.Request.Headers.Keys) { switch (str) { case "Accept": hwrRequest.Accept = context.Request.Headers["Accept"]; break; case "Connection": hwrRequest.KeepAlive = true; break; case "Content-Length": hwrRequest.ContentLength = int.Parse(context.Request.Headers["Content-Length"]); break; case "Content-Type": //hwrRequest.ContentType = context.Request.Headers["Content-Type"]; hwrRequest.ContentType = "application/x-www-form-urlencoded"; //表头的格式必须要写,否则请求响应的页面得不到要传递的值 break; case "Expect": goto default; break; case "Date": goto default; break; case "Host": break; case "If-Modified-Since": goto default; break; case "Range": goto default; break; case "Referer": hwrRequest.Referer = context.Request.Headers["Referer"]; break; case "Transfer-Encoding": goto default; break; case "User-Agent": //hwrRequest.UserAgent = context.Request.Headers["User-Agent"]; //模拟客户端浏览器为IE hwrRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)"; break; case "Accept-Encoding": hwrRequest.Headers.Add("Accept-Encoding", context.Request.Headers["Accept-Encoding"]); break; case "Accept-Language": hwrRequest.Headers.Add("Accept-Language", context.Request.Headers["Accept-Language"]); break; default: if (context.Request.Headers.AllKeys.Contains(str)) hwrRequest.Headers.Add(str, context.Request.Headers[str]); break; } } hwrRequest.AllowAutoRedirect = true; switch (context.Request.HttpMethod) { case "GET": hwrRequest.Method = "GET"; break; case "POST": hwrRequest.Method = "POST"; string postBodyStr = ""; //Post请求包体内容 //获取POST请求包体 using (Stream stream = context.Request.InputStream) using (StreamReader sReader = new StreamReader(stream, Encoding.UTF8)) { try { postBodyStr = sReader.ReadToEnd(); //读取请求参数的包体内容 if (!string.IsNullOrEmpty(postBodyStr)) { byte[] postBodyBytes = Encoding.Default.GetBytes(postBodyStr);//传递的值 hwrRequest.ContentLength = postBodyBytes.Length; //把传递的值写到流中 using (System.IO.Stream newStream = hwrRequest.GetRequestStream()) { try { newStream.Write(postBodyBytes, 0, postBodyBytes.Length); } catch (Exception ex) { throw ex; } } } } catch (Exception ex) { throw ex; } } break; default: throw new HttpException("未支持的请求方式!"); } //为请求添加验证信息 FileHelper.AttachAuthenticationInfo(newUrl, hwrRequest, docType); //处理返回信息 using (HttpWebResponse hwrResponse = hwrRequest.GetResponse() as HttpWebResponse) using (Stream stream = hwrResponse.GetResponseStream()) //using (StreamReader sReader = new StreamReader(stream, Encoding.UTF8)) { StreamReader sReader = null; try { string fileType = string.Format("*{0}", newUrl.Substring(newUrl.LastIndexOf("."))); switch (fileType) { case "*.sql": sReader = new StreamReader(stream, Encoding.GetEncoding("GB2312")); break; default: sReader = new StreamReader(stream, Encoding.UTF8); break; } if (_allowFileType.Contains(fileType)) { string fileName = newUrl.Substring(newUrl.LastIndexOf("/") + 1); //设置文件类型 //context.Response.ContentType = getFileContentTypeTag(fileType); context.Response.ContentType = hwrResponse.Headers["Content-Type"]; //文件名称 //context.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName)); //HttpUtility以UTF-8编码,会截断文件名。 context.Response.AddHeader("Content-Disposition", "attachment;filename=" + context.Server.UrlEncode(fileName).Replace("+","%20")); //处理文件 byte[] fileBuffer = new byte[1024]; byte[] srcTrans; int readFileSize = 0; while ((readFileSize = stream.Read(fileBuffer, 0, fileBuffer.Length)) > 0) { srcTrans = copyContentFromByteArray(fileBuffer, readFileSize); context.Response.BinaryWrite(srcTrans); } context.Response.End(); } else { //处理html string responseHTML = sReader.ReadToEnd(); if (!string.IsNullOrEmpty(responseHTML)) { string pattern = "<\\s*a\\s*href=[\"'](?!http://).*?<\\s*/\\s*a\\s*>"; Regex reg = new Regex(pattern, RegexOptions.IgnoreCase); MatchCollection matches = reg.Matches(responseHTML); string tmpLnkTag = ""; string tmpFront = ""; switch (docType) { case DocumentFileType.Vstf: tmpFront = "http://" + hwrRequest.RequestUri.Authority; break; case DocumentFileType.InnerSvn: goto case DocumentFileType.OuterSvn; break; case DocumentFileType.OuterSvn: tmpFront = hwrRequest.RequestUri.AbsoluteUri; break; case DocumentFileType.SharedDir: goto default; break; case DocumentFileType.TD: goto default; break; default: break; } foreach (Match match in matches) { tmpLnkTag = match.Value.Replace("HREF=\"", "HREF=\"" + tmpFront).Replace("href=\"", "href=\"" + tmpFront); responseHTML = responseHTML.Replace(match.Value, tmpLnkTag); } context.Response.Write(responseHTML); context.Response.End(); } } } catch (Exception ex) { throw ex; } finally { if (sReader != null) sReader.Close(); } } } else { //处理共享文件 //StreamReader sReader = null; string fileType = string.Format("*{0}", newUrl.Substring(newUrl.LastIndexOf("."))); //switch (fileType) //{ // case "*.sql": // sReader = new StreamReader(stream, Encoding.GetEncoding("GB2312")); // break; // default: // sReader = new StreamReader(stream, Encoding.UTF8); // break; //} string resourcePath = ""; try { if (_allowFileType.Contains(fileType)) { string fileName = newUrl.Substring(newUrl.LastIndexOf("\\") + 1); resourcePath = newUrl.Replace(fileName, ""); int status = FileSharedHelper.ConnectResource(resourcePath); if (status == 1219) //1219表示文件共享连接已建立, 需强制断开. { FileSharedHelper.ForceDisconnectResource(resourcePath); status = FileSharedHelper.ConnectResource(resourcePath); } if (status != 0) throw new FileLoadException("ConnectionError: ERROR_ID " + status.ToString()); string filePath = resourcePath + fileName; //设置文件类型 context.Response.ContentType = getFileContentTypeTag(fileType); //文件名称 context.Response.AddHeader("Content-Disposition", "attachment;filename=" + context.Server.UrlEncode(fileName).Replace("+", "%20")); //处理文件 using (FileStream fsStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { byte[] fileBuffer = new byte[1024]; byte[] srcTrans; int readFileSize = 0; while ((readFileSize = fsStream.Read(fileBuffer, 0, fileBuffer.Length)) > 0) { srcTrans = copyContentFromByteArray(fileBuffer, readFileSize); context.Response.BinaryWrite(srcTrans); } } //context.Response.End(); } else { //处理共享文件目录 bool status = FileSharedHelper.OpenShareFolder(newUrl); if (!status) { FileSharedHelper.CloseShareFolder(newUrl); FileSharedHelper.OpenShareFolder(newUrl); FileSharedHelper.ExplorerShareFolderByWinMsg(newUrl); } else FileSharedHelper.ExplorerShareFolderByWinMsg(newUrl); } } catch (Exception ex) { throw new Exception("共享文件无法打开, 请检查用户名及口令! \r\n错误信息:" + ex.Message); } finally { if (!string.IsNullOrEmpty(resourcePath)) FileSharedHelper.DisconnectResource(resourcePath); context.Response.Write(getCloseWindowHTML()); } } } } public bool IsReusable { get { return false; } } private byte[] copyContentFromByteArray(byte[] conByte, int conLength) { byte[] result = new byte[conLength]; for (int i = 0; i < conLength; i++) result[i] = conByte[i]; return result; } private string getFileContentTypeTag(string fileType) { string result = ""; switch (fileType.ToLower()) { case "*.asf ": result = "video/x-ms-asf "; break; case "*.avi ": result = "video/avi "; break; case "*.doc ": result = "application/msword "; break; case "*.docx ": result = "application/vnd.openxmlformats-officedocument.wordprocessingml.document "; break; case "*.ppt ": result = "application/vnd.ms-powerpoint "; break; case "*.pptx ": result = "application/vnd.openxmlformats-officedocument.presentationml.presentation "; break; case "*.zip ": result = "application/zip "; break; case "*.xls ": result = "application/vnd.ms-excel "; break; case "*.xlsx ": result = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet "; break; case "*.gif ": result = "image/gif "; break; case "*.jpg ": result = "image/jpeg "; break; case "*.jpeg ": result = "image/jpeg "; break; case "*.wav ": result = "audio/wav "; break; case "*.mp3 ": result = "audio/mpeg3 "; break; case "*.mpg ": result = "video/mpeg "; break; case "*.mepg ": result = "video/mpeg "; break; case "*.rtf ": result = "application/rtf "; break; case "*.html ": result = "text/html "; break; case "*.htm ": result = "text/html "; break; case "*.txt ": result = "text/plain "; break; case "*.sql ": result = "text/plain "; break; default: result = "application/octet-stream "; break; } return result; } /// <summary> /// 生成一段用来关闭窗口的HTML /// </summary> /// <returns>System.String类型, 表示用来关闭窗口的HTML内容. </returns> private string getCloseWindowHTML() { string content = @"<html> <head> <script type='text/javascript'> function closeWindow(){ window.opener=null; window.open('','_self',''); window.close(); } </script> </head> <body onload='closeWindow()'> </body> </html>"; return content; } } }
//文件地址变换代码, FileHelper
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Configuration; using Microsoft.TeamFoundation.Client; using Microsoft.TeamFoundation.VersionControl.Client; using Microsoft.TeamFoundation.WorkItemTracking.Client; using System.Text.RegularExpressions; using System.Net; using System.Text; namespace WebSite.Common { public class FileHelper { private static readonly string _vstfPath = ConfigurationManager.AppSettings["VstfPath"]; private static readonly string _vstfUName = ConfigurationManager.AppSettings["VstfUName"]; private static readonly string _vstfPwd = ConfigurationManager.AppSettings["VstfPwd"]; private static readonly string _vstfDomain = ConfigurationManager.AppSettings["VstfDomain"]; private static readonly string _svnPath = ConfigurationManager.AppSettings["SVNPath"]; private static readonly string _svnName = ConfigurationManager.AppSettings["SVNUName"]; private static readonly string _svnPwd = ConfigurationManager.AppSettings["SVNPwd"]; private static readonly string _vstfFileCenter = ConfigurationManager.AppSettings["VstfFileCenter"]; private static readonly string _OuterDepSvnName = ConfigurationManager.AppSettings["OutDepartmentSVNName"]; private static readonly string _OuterDepSvnPwd = ConfigurationManager.AppSettings["OutDepartmentSVNPwd"]; /// <summary> /// VSTF映射本地路径 /// </summary> private static readonly string _localPath = ConfigurationManager.AppSettings["LocalPath"]; private static TeamFoundationServer tfs = new TeamFoundationServer(_vstfPath, new System.Net.NetworkCredential(_vstfUName, _vstfPwd, _vstfDomain)); private static VersionControlServer vcs = tfs.GetService(typeof(VersionControlServer)) as VersionControlServer; private static readonly string[] _allowFileType = new string[] { "*.doc", "*.docx", "*.xls", "*.xlsx", "*.ppt", "*.pptx", "*.sql", "*.gz","*.txt", "*.rtf" }; /// <summary> /// 根据请求的源地址, 获取文档文件的Web响应对象. /// </summary> /// <param name="srcFilePath">System.String类型, 表示原始文档文件的地址.</param> /// <param name="docType">System.Enum类型, 表示文档文件的类型. </param> /// <returns>System.Net.HttpWebResponse类型, 表示返回的Web响应对象. </returns> public static DocumentFileType GetTransferedUrl(HttpContext context, ref string srcFilePath) { //srcFilePath = HttpUtility.UrlDecode(srcFilePath); srcFilePath = context.Server.UrlDecode(srcFilePath); DocumentFileType result = DocumentFileType.OuterSvn; if(!string.IsNullOrEmpty(srcFilePath)) { srcFilePath = HttpUtility.UrlDecode(srcFilePath); if (srcFilePath.StartsWith("$/")) { srcFilePath = filePathTranslator(srcFilePath, DocumentFileType.Vstf); result = DocumentFileType.Vstf; } else if (srcFilePath.StartsWith("\\")) { srcFilePath = filePathTranslator(srcFilePath, DocumentFileType.SharedDir); result = DocumentFileType.SharedDir; } else if (srcFilePath.StartsWith("http://")) { if (srcFilePath.EndsWith("/tdbin/start_a.htm")) { srcFilePath = filePathTranslator(srcFilePath, DocumentFileType.TD); result = DocumentFileType.TD; } else if (srcFilePath.StartsWith(_svnPath)) { srcFilePath = filePathTranslator(srcFilePath, DocumentFileType.InnerSvn); result = DocumentFileType.InnerSvn; } else { srcFilePath = filePathTranslator(srcFilePath, DocumentFileType.OuterSvn); result = DocumentFileType.OuterSvn; } } else srcFilePath = ""; } return result; } /// <summary> /// 根据文档所属的服务器类型将身份验证信息添加到给定的Web请求对象中. /// </summary> /// <param name="srcPath">System.String类型, 表示文档文件的地址. </param> /// <param name="request">System.Net.HttpWebRequest类型, 表示用于转发请求的Request对象. </param> /// <param name="docType"></param> /// <param name="docType">System.Enum类型, 表示请求文档所属的服务器类型. </param> public static void AttachAuthenticationInfo(string url, HttpWebRequest request, DocumentFileType docType) { string name = ""; string pwd = ""; switch (docType) { case DocumentFileType.InnerSvn: name = _svnName; pwd = _svnPwd; break; case DocumentFileType.SharedDir: goto case DocumentFileType.OuterSvn; break; case DocumentFileType.OuterSvn: name = _OuterDepSvnName; pwd = _OuterDepSvnPwd; break; case DocumentFileType.TD: break; case DocumentFileType.Vstf: break; default: break; } attachCredentialCache(url, request, name, pwd, docType); } #region private Method /// <summary> /// 根据请求的文档文件路径级文档的类型, 获取对应文档文件的Web地址. /// </summary> /// <param name="srcFilePath">System.String类型, 表示原始文档文件的地址. </param> /// <param name="docType">System.Enum类型, 表示文档文件的类型. </param> /// <returns>System.String类型, 表示经过变换的文档文件的地址. </returns> private static string filePathTranslator(string srcFilePath, DocumentFileType docType) { string result = ""; if (!string.IsNullOrEmpty(srcFilePath)) { switch(docType) { case DocumentFileType.Vstf: string regStr = "^\\$/[\\w\\.]+/[^\\s/]"; //必须以$/xxx/s开头的文件才行 Regex reg = new Regex(regStr); if (reg.IsMatch(srcFilePath)) { getFileFromVstfTo160(srcFilePath); result = srcFilePath.Replace("$/", _vstfFileCenter); } break; case DocumentFileType.InnerSvn: goto default; break; case DocumentFileType.OuterSvn: goto default; break; case DocumentFileType.SharedDir: //result = string.Format("file:{0}", srcFilePath.Replace("\\", "/")); goto default; break; case DocumentFileType.TD: result = ""; break; default: result = srcFilePath; break; } } return result; } /// <summary> /// 根据允许访问的文件类型从VSTF上获取文件到ServerDeploy目录 /// </summary> /// <param name="srcFilePath">System.String类型, 表示以$开头的VSTF文件路径. </param> private static void getFileFromVstfTo160(string srcFilePath) { if (srcFilePath.StartsWith("$/")) { //srcFilePath = HttpUtility.UrlDecode(srcFilePath); Item[] items = vcs.GetItems(srcFilePath, RecursionType.Full).Items; string csprojPath; string fileType; foreach (Item it in items) { if (it.ServerItem.Contains(".")) { fileType = it.ServerItem.Substring(it.ServerItem.LastIndexOf(".")); if (_allowFileType.Contains("*" + fileType)) { csprojPath = _localPath + it.ServerItem.Substring(2); it.DownloadFile(csprojPath); } } } } } /// <summary> /// 根据请求的文档文件路径、用户名及密码获取HttpWebResponse对象 /// </summary> /// <param name="srcPath">System.String类型, 表示文档文件的地址. </param> /// <param name="request">System.Net.HttpWebRequest类型, 表示用于转发请求的Request对象. </param> /// <param name="svnName">System.String类型, 表示发起请求的账户名. </param> /// <param name="svnPwd">System.String类型, 表示发起请求的密码. </param> /// <param name="docType">System.Enum类型, 表示请求文档所属的服务器类型. </param> private static void attachCredentialCache(string srcPath,HttpWebRequest request, string svnName, string svnPwd, DocumentFileType docType) { if (!(string.IsNullOrEmpty(svnName) || string.IsNullOrEmpty(svnPwd))) { CredentialCache myCache = new CredentialCache(); NetworkCredential netCredential = new NetworkCredential(svnName,svnPwd); switch (docType) { case DocumentFileType.SharedDir: netCredential.Domain = "feinno.com"; break; case DocumentFileType.TD: break; default: break; } myCache.Add(new Uri(srcPath), "Basic", netCredential); request.Credentials = myCache; request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(svnName + ":" + svnPwd)); } } #endregion } public enum DocumentFileType { Vstf = 1, InnerSvn = 2, OuterSvn = 3, SharedDir = 4, TD = 5 } }
//文件共享服务器中的文件处理代码, FileSharedHelper
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Runtime.InteropServices; using System.Configuration; using System.Text.RegularExpressions; using System.Diagnostics; namespace WebSite.Common { public class FileSharedHelper { private static readonly string _OuterDepSvnName = ConfigurationManager.AppSettings["OutDepartmentSVNName"]; private static readonly string _OuterDepSvnPwd = ConfigurationManager.AppSettings["OutDepartmentSVNPwd"]; #region WMI访问文件共享 /// <summary> /// 建立到服务器资源的连接 /// </summary> /// <param name="resourcePath">System.String类型, 表示指定本地驱动器或远程共享资源.</param> /// <returns>System.Unit类型, 如果方法执行成功返回0(NO_ERROR), 否则返回ERROR_CODE.</returns> public static int ConnectResource(string resourcePath) { int result = -1; if (resourcePath.StartsWith("\\")) { //string pattern = "[\\d]{1,3}.[\\d]{1,3}.[\\d]{1,3}.[\\d]{1,3}"; //Regex reg = new Regex(pattern); //if (reg.IsMatch(resourcePath)) //{ // string ipAddress = ""; // ipAddress = reg.Match(resourcePath).Value; //result = Convert.ToInt32(WNetAddConnection(string.Format("{0}/{1}", "", _OuterDepSvnName), _OuterDepSvnPwd, resourcePath, null)); result = Convert.ToInt32(WNetAddConnection(_OuterDepSvnName, _OuterDepSvnPwd, resourcePath, "")); //} } return result; } /// <summary> /// 断开到服务器资源的连接 /// </summary> /// <param name="resourcePath">System.String类型, 表示指定本地驱动器或远程共享资源.</param> /// <returns>System.Unit类型, 如果方法执行成功返回0(NO_ERROR), 否则返回ERROR_CODE.</returns> public static int DisconnectResource(string resourcePath) { int result = -1; if (resourcePath.StartsWith("\\")) { result = Convert.ToInt32(WNetCancelConnection(resourcePath, 1, true)); } return result; } /// <summary> /// 强制断开资源 /// </summary> /// <param name="resourcePath">System.String类型, 表示资源的路径. </param> public static void ForceDisconnectResource(string resourcePath) { string cmd = string.Format("NET USE {0} /DELETE /Y", resourcePath); WinExec(cmd, Convert.ToUInt16((int)ShowWindow.SW_HIDE)); } /// <summary> /// 强制断开远程资源 /// </summary> /// <param name="winExecCommand">System.String类型, 表示要断开资源的命令</param> /// <param name="showWindowOption">System.Unit类型, 表示显示窗口的相关属性.</param> /// <returns>System.Unit, 表示是否成功断开资源. </returns> [DllImport("kernel32.dll", EntryPoint = "WinExec")] private static extern uint WinExec(string winExecCommand, uint showWindowOption); //mpr.dll是Windws操作系统网络通讯相关模块,通过对功能需求的分析,直接调用mpr.dll来实现该功能。 /// <summary> /// 添加远程网络连接. /// </summary> /// <param name="lpNetResource">WebSite.Common.NetResource类型, 表示包含网络访问资源的结构. </param> /// <param name="lpPassword">System.String类型, 表示远程计算机的密码. </param> /// <param name="lpUsername">System.String类型, 表示远程计算机的用户名. </param> /// <param name="dwFlags">System.Unit类型, 表示连接选项. 可选值CONNECT_INTERACTIVE、CONNECT_PROMPT、CONNECT_REDIRECT、CONNECT_UPDATE_PROFILE、CONNECT_COMMANDLINE、CONNECT_CMD_SAVECRED</param> /// <returns>System.Unit类型, 如果方法执行成功返回0(NO_ERROR), 否则返回ERROR_CODE.</returns> [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")] private static extern uint WNetAddConnection2(NetResource lpNetResource, string lpPassword, string lpUsername, uint dwFlags); /// <summary> /// 释放存在的网络连接. /// </summary> /// <param name="lpName">System.String类型, 表示指定本地驱动器或远程共享资源. </param> /// <param name="dwFlags">System.Unit类型, 表示断开连接方式, 可设置0或CONNECT_UPDATE_PROFILE. </param> /// <param name="fForce">System.Boolean类型, 表示是否强制断开连接. </param> /// <returns>System.Unit类型, 如果方法执行成功返回0(NO_ERROR), 否则返回ERROR_CODE.</returns> [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")] private static extern uint WNetCancelConnection2(string lpName, uint dwFlags, bool fForce); /// <summary> /// 添加远程网络连接. /// </summary> /// <param name="netResource">WebSite.Common.NetResource类型, 表示包含网络访问资源的结构. </param> /// <param name="username">System.String类型, 表示远程计算机的用户名.</param> /// <param name="password">System.String类型, 表示远程计算机的密码.</param> /// <returns>System.Unit类型, 如果方法执行成功返回0(NO_ERROR), 否则返回ERROR_CODE.</returns> private static uint WNetAddConnection(NetResource netResource, string username, string password) { uint result = WNetAddConnection2(netResource, password, username, 0); return result; } /// <summary> /// 添加远程网络连接. /// </summary> /// <param name="username">System.String类型, 表示远程计算机的用户名.</param> /// <param name="password">System.String类型, 表示远程计算机的密码.</param> /// <param name="remoteName">System.String类型, 表示远程计算机资源路径.</param> /// <param name="localName">System.String类型, 表示将远程计算机映射为本地资源的名称.</param> /// <returns>System.Unit类型, 如果方法执行成功返回0(NO_ERROR), 否则返回ERROR_CODE.</returns> private static uint WNetAddConnection(string username, string password, string remoteName, string localName) { NetResource netResource = new NetResource(); netResource.dwScope = 2; //RESOURCE_GLOBALNET netResource.dwType = 1; //RESOURCETYPE_DISK netResource.dwDisplayType = 3; //RESOURCEDISPLAYTYPE_SHARE 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; } /// <summary> /// 释放存在的网络连接. /// </summary> /// <param name="name">System.String类型, 表示指定本地驱动器或远程共享资源. </param> /// <param name="flags">System.Unit类型, 表示断开连接方式, 可设置0或CONNECT_UPDATE_PROFILE.</param> /// <param name="force">System.Boolean类型, 表示是否强制断开连接. </param> /// <returns>System.Unit类型, 如果方法执行成功返回0(NO_ERROR), 否则返回ERROR_CODE.</returns> private static uint WNetCancelConnection(string name, uint flags, bool force) { uint nret = WNetCancelConnection2(name, flags, force); return nret; } #endregion #region CMD访问文件共享 /// <summary> /// 打开给定的文件共享内容 /// </summary> /// <param name="sourcePath">System.String类型, 表示给定的共享资源路径. </param> /// <returns>System.Boolean类型, 表示是否成功打开共享资源. </returns> private static bool openShareFolder(string sourcePath, string name, string pwd) { string cmdLineInfo = "net use " + sourcePath + " /User:\"" + name + "\" \"" + pwd + "\" /PERSISTENT:NO"; return executeCommandLine(cmdLineInfo); } public static bool ExplorerShareFolder(string sourcePath) { string cmdLineInfo = "explorer " + sourcePath; return executeCommandLine(cmdLineInfo); } public static void ExplorerShareFolderByWinMsg(string sourcePath) { explorerShareFolder(sourcePath); } /// <summary> /// 打开给定的文件共享内容 /// </summary> /// <param name="sourcePath">System.String类型, 表示给定的共享资源路径. </param> /// <returns>System.Boolean类型, 表示是否成功打开共享资源. </returns> public static bool OpenShareFolder(string sourcePath) { return openShareFolder(sourcePath, _OuterDepSvnName, _OuterDepSvnPwd); } /// <summary> /// 断开给定的文件共享内容 /// </summary> /// <param name="sourcePath">System.String类型, 表示给定的共享资源路径. </param> /// <returns>System.Boolean类型, 表示断开是否成功. </returns> public static bool CloseShareFolder(string sourcePath) { return closeShareFolder(sourcePath, _OuterDepSvnName, _OuterDepSvnPwd); } /// <summary> /// 断开给定的文件共享内容 /// </summary> /// <param name="sourcePath">System.String类型, 表示给定的共享资源路径. </param> /// <returns>System.Boolean类型, 表示断开是否成功. </returns> private static bool closeShareFolder(string sourcePath, string name, string pwd) { //string cmdLineInfo = "net use " + sourcePath + " /User:\"" + name + "\" \"" + pwd + "\" /DELETE"; string cmdLineInfo = "net use " + sourcePath + " /DELETE"; return executeCommandLine(cmdLineInfo); } /// <summary> /// 强制断开资源 /// </summary> /// <param name="resourcePath">System.String类型, 表示资源的路径. </param> private static void explorerShareFolder(string resourcePath) { string cmd = string.Format("explorer {0}", resourcePath); WinExec(cmd, Convert.ToUInt16((int)ShowWindow.SW_HIDE)); } /// <summary> /// 在Command命令行窗口执行给定的指令. /// </summary> /// <param name="commandLineInfo">System.String类型, 表示将要在命令行窗口执行的指令. </param> /// <returns>System.Boolean类型, 表示命令行是否成功执行. </returns> private static bool executeCommandLine(string commandLineInfo) { bool result = false; using (Process proc = getCommandLineProcess()) { //try //{ proc.Start(); proc.StandardInput.WriteLine(commandLineInfo); proc.StandardInput.WriteLine("exit"); while (!proc.HasExited) proc.WaitForExit(); string errorInfo = proc.StandardError.ReadToEnd(); proc.StandardError.Close(); if (string.IsNullOrEmpty(errorInfo)) result = true; // else // throw new Exception(errorInfo); //} //catch (Exception ex) //{ // throw ex; //} } return result; } /// <summary> /// 获取CMD命令行对象 /// </summary> /// <returns>System.Diagnostics.Process, 表示返回的CMD进程对象. </returns> private static Process getCommandLineProcess() { Process proc = new Process(); proc.StartInfo.FileName = "cmd.exe"; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.CreateNoWindow = true; return proc; } #endregion } /// <summary> /// 通过多个字段指定网络连接资源信息. /// </summary> [StructLayout(LayoutKind.Sequential)] public class NetResource { //dwScope: 指定枚举范围. 设置RESOURCE_CONNECTED,RESOURCE_GLOBALNET,RESOURCE_REMEMBERED三值之一. public int dwScope; //指定访问的资源类型. 设置三个值之一. RESOURCETYPE_ANY表示所有资源; RESOURCETYPE_DISK表示磁盘资; RESOURCETYPE_PRINT表示打印机. public int dwType; //指出资源显示类型. RESOURCEDISPLAYTYPE_DOMAIN;RESOURCEDISPLAYTYPE_SERVER;RESOURCEDISPLAYTYPE_SHARE;RESOURCEDISPLAYTYPE_GENERIC. public int dwDisplayType; //描述资源的使用方式. 设置RESOURCEUSAGE_CONNECTABLE或RESOURCEUSAGE_CONTAINER. public int dwUsage; //lpLocalName: 同dwScope关联, 指定本地映射. public string lpLocalName; //远程访问文件夹路径. public string lpRemoteName; //资源描述. public string lpComment; //资源提供者, 可以设置为NULL. public string lpProvider; } public enum ShowWindow { SW_FORCEMINIMIZE = 0, SW_HIDE = 1, SW_MAXIMIZE = 2, SW_MINIMIZE = 3, SW_RESTORE = 4, SW_SHOW = 5, SW_SHOWDEFAULT = 6, SW_SHOWMAXIMIZED = 7, SW_SHOWMINIMIZED = 8, SW_SHOWMINNOACTIVE = 9, SW_SHOWNA = 10, SW_SHOWNOACTIVATE = 11, SW_SHOWNORMAL = 12 } }
偷懒的地方太多, 仅仅为了实现功能, 考虑不周还望见谅!