IIS/ASP.NET访问共享文件夹的可用方式

【截止2014-10-14】

 

网上搜索了很多篇文章,所提及的总共有两种方式:

1.Asp.Net模拟登陆;

例如:

实战ASP.NET访问共享文件夹(含详细操作步骤)

实现一个2008serve的IIS的虚拟目录(通过网络路径(UNC)的形式,共享在另外一个2008服务器上

 

2.调用Windows API 的 WNetAddConnection2 、WNetCancelConnection2函数;

例如:

ASP.NET网络映射驱动器无权限访问的解决方案
ASP.NET访问网络驱动器(映射磁盘)

共享访问在.NET中的编程实现

 

 

相对来说,第一种方式是最直接的,且改动较小的。但不足之处就是比较依赖共享所在服务器(如果切换共享服务器地址,那么本地的用户名和密码都要作调整。);

而第二种方式缺点(个人感觉),API函数的不稳定、链接数超出限制、内存泄露等不稳定的问题(如果有哪位朋友有解决方案,还请告知,谢谢)。

 

ps:折腾了两天,先用第一种方式吧。附上一个第二种方式的辅助类。

 

  1 #define CheckReturn

  2 using System;

  3 using System.Collections.Generic;

  4 using System.Text;

  5 using System.Runtime.InteropServices;

  6 

  7 

  8 /// <summary>

  9 /// 网络资源访问

 10 /// </summary>

 11 public class WNetConnectionHelper : IDisposable

 12 {

 13 

 14     /// <summary>

 15     /// 添加远程网络连接。

 16     /// </summary>

 17     /// <param name="lpNetResource">是一个包含网络访问资源的结构,在这里作为参数用来指定详细的网络连接信息</param>

 18     /// <param name="lpPassword">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>

 19     /// <param name="lpUsername">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>

 20     /// <param name="dwFlags">指出连接选项,包含六种设置</param>

 21     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>

 22     [DllImport("Mpr.dll", EntryPoint = "WNetAddConnection2")]

 23     /*

 24     private static extern uint WNetAddConnection2(NetResource lpNetResource, [MarshalAs(UnmanagedType.LPStr)]string lpPassword, [MarshalAs(UnmanagedType.LPStr)]string lpUsername, uint dwFlags);

 25     */

 26     private static extern uint WNetAddConnection2(IntPtr lpNetResource, string lpPassword, string lpUsername, uint dwFlags);

 27 

 28     /// <summary>

 29     /// 释放存在的网络连接。

 30     /// </summary>

 31     /// <param name="lpName">指定本地驱动器或远程共享资源</param>

 32     /// <param name="dwFlags">表示断开连接方式。设置 0 或CONNECT_UPDATE_PROFILE。</param>

 33     /// <param name="fForce">如果当前正在使用远程资源,是否进行强制断开连接。如果设置FALSE,在有远程资源使用的情况下关闭连接操作将会失败。</param>

 34     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>

 35     [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")]

 36     private static extern uint WNetCancelConnection2([MarshalAs(UnmanagedType.LPStr)]string lpName, uint dwFlags, int fForce);

 37 

 38 

 39     /// <summary>

 40     /// 获取网络错误的扩展错误信息

 41     /// </summary>

 42     /// <param name="lpError">指定一个变量,用于装载网络错误代码。具体的代码由网络供应商决定</param>

 43     /// <param name="lpErrorBuf">指定一个字串缓冲区,用于装载网络错误的说明</param>

 44     /// <param name="nErrorBufSize">lpErrorBuf缓冲区包含的字符数量</param>

 45     /// <param name="lpNameBuf">用于装载网络供应商名字的字串缓冲区</param>

 46     /// <param name="nNameBufSize">lpNameBuf缓冲区的字符数量</param>

 47     /// <returns></returns>

 48     [DllImport("Mpr.dll", EntryPoint = "WNetGetLastError")]

 49     private static extern uint WNetGetLastError(ref uint lpError, [MarshalAs(UnmanagedType.LPStr)]ref string lpErrorBuf, long nErrorBufSize, [MarshalAs(UnmanagedType.LPStr)]ref  string lpNameBuf, uint nNameBufSize);

 50 

 51     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]

 52     public struct NetResource

 53     {

 54         /// <summary>

 55         /// 指定枚举范围。设置RESOURCE_CONNECTED,RESOURCE_GLOBALNET,RESOURCE_REMEMBERED三值之一。

 56         /// </summary>

 57         public int dwScope;

 58         /// <summary>

 59         /// 指定访问的资源类型。设置三个值之一。RESOURCETYPE_ANY表示所有资源;RESOURCETYPE_DISK表示磁盘资源;RESOURCETYPE_PRINT表示打印机。

 60         /// </summary>

 61         public int dwType;

 62         /// <summary>

 63         /// 指出资源显示类型。RESOURCEDISPLAYTYPE_DOMAIN;RESOURCEDISPLAYTYPE_SERVER;RESOURCEDISPLAYTYPE_SHARE;RESOURCEDISPLAYTYPE_GENERIC。

 64         /// </summary>

 65         public int dwDisplayType;

 66         /// <summary>

 67         /// 描述资源的使用方式。设置RESOURCEUSAGE_CONNECTABLE 或RESOURCEUSAGE_CONTAINER。

 68         /// </summary>

 69         public int dwUsage;

 70         /// <summary>

 71         /// 同dwScope关联,指定本地映射。

 72         /// </summary>

 73         //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

 74         public string lpLocalName;

 75         /// <summary>

 76         /// 远程访问文件夹路径。

 77         /// </summary>

 78         //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

 79         public string lpRemoteName;

 80         /// <summary>

 81         /// 描述。

 82         /// </summary>

 83         //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

 84         public string lpComment;

 85         /// <summary>

 86         /// 资源提供者,可以设置为NULL。

 87         /// </summary>

 88         //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

 89         public string lpProvider;

 90     }

 91 

 92 

 93     public enum RESOURCE_SCOPE

 94     {

 95         RESOURCE_CONNECTED = 1,

 96         RESOURCE_GLOBALNET = 2,

 97         RESOURCE_REMEMBERED = 3,

 98         RESOURCE_RECENT = 4,

 99         RESOURCE_CONTEXT = 5

100     }

101 

102     public enum RESOURCE_TYPE

103     {

104         RESOURCETYPE_ANY = 0,

105         RESOURCETYPE_DISK = 1,

106         RESOURCETYPE_PRINT = 2,

107         RESOURCETYPE_RESERVED = 8,

108     }

109 

110     public enum RESOURCE_USAGE

111     {

112         RESOURCEUSAGE_CONNECTABLE = 1,

113         RESOURCEUSAGE_CONTAINER = 2,

114         RESOURCEUSAGE_NOLOCALDEVICE = 4,

115         RESOURCEUSAGE_SIBLING = 8,

116         RESOURCEUSAGE_ATTACHED = 16,

117         RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),

118     }

119 

120     public enum RESOURCE_DISPLAYTYPE

121     {

122         RESOURCEDISPLAYTYPE_GENERIC = 0,

123         RESOURCEDISPLAYTYPE_DOMAIN = 1,

124         RESOURCEDISPLAYTYPE_SERVER = 2,

125         RESOURCEDISPLAYTYPE_SHARE = 3,

126         RESOURCEDISPLAYTYPE_FILE = 4,

127         RESOURCEDISPLAYTYPE_GROUP = 5,

128         RESOURCEDISPLAYTYPE_NETWORK = 6,

129         RESOURCEDISPLAYTYPE_ROOT = 7,

130         RESOURCEDISPLAYTYPE_SHAREADMIN = 8,

131         RESOURCEDISPLAYTYPE_DIRECTORY = 9,

132         RESOURCEDISPLAYTYPE_TREE = 10,

133         RESOURCEDISPLAYTYPE_NDSCONTAINER = 11

134     }

135 

136 

137     /// <summary>

138     /// 添加远程网络连接。

139     /// </summary>

140     /// <param name="netResource">是一个包含网络访问资源的结构,在这里作为参数用来指定详细的网络连接信息</param>

141     /// <param name="username">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>

142     /// <param name="password">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>

143     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>

144     public static uint WNetAddConnection(NetResource netResource, string username, string password)

145     {

146         IntPtr ptr_netResource = IntPtr.Zero;

147         try

148         {

149             //分配内存

150             ptr_netResource = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(netResource));

151             System.Runtime.InteropServices.Marshal.StructureToPtr(netResource, ptr_netResource, false);

152 

153             uint result = WNetAddConnection2(ptr_netResource, password, username, 0);

154             return result;

155         }

156         finally

157         {

158             if (ptr_netResource != IntPtr.Zero)

159                 System.Runtime.InteropServices.Marshal.FreeCoTaskMem(ptr_netResource);

160         }

161         /*

162         uint result = WNetAddConnection2(netResource, password, username, 0);

163         return result;

164         */

165     }

166 

167     /// <summary>

168     /// 添加远程网络连接。

169     /// </summary>

170     /// <param name="username">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>

171     /// <param name="password">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>

172     /// <param name="remoteName">远程访问文件夹路径。</param>

173     /// <param name="localName">同dwScope关联,指定本地映射。</param>

174     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>

175     public static uint WNetAddConnection(string username, string password, string remoteName, string localName)

176     {

177         NetResource netResource = new NetResource();

178         netResource.dwScope = 2;       //RESOURCE_GLOBALNET

179         netResource.dwType = 1;       //RESOURCETYPE_DISK

180         netResource.dwDisplayType = 3; //RESOURCEDISPLAYTYPE_SHARE

181         netResource.dwUsage = 1;       //RESOURCEUSAGE_CONNECTABLE

182         netResource.lpLocalName = localName;

183         netResource.lpRemoteName = remoteName.TrimEnd('/');

184         //netResource.lpRemoteName = lpComment;

185         //netResource.lpProvider = null;

186         uint result = WNetAddConnection(netResource, username, password);

187         return result;

188     }

189 

190     /// <summary>

191     /// 添加远程网络连接。

192     /// </summary>

193     /// <param name="name">指定本地驱动器或远程共享资源</param>

194     /// <param name="flags">表示断开连接方式。设置 0 或CONNECT_UPDATE_PROFILE。</param>

195     /// <param name="force">如果当前正在使用远程资源,是否进行强制断开连接。如果设置FALSE,在有远程资源使用的情况下关闭连接操作将会失败。</param>

196     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>

197     public static uint WNetCancelConnection(string name, uint flags, bool force)

198     {

199         uint nret = WNetCancelConnection2(name, flags, force ? 1 : 0);

200         return nret;

201     }

202 

203 

204     #region SelfUsing

205     bool connectSuccess = false;

206     string username, password, remoteName, localName;

207     private WNetConnectionHelper(string username, string password, string remoteName, string localName)

208     {

209         this.username = username;

210         this.password = password;

211         this.remoteName = remoteName;

212         this.localName = localName;

213         Close();

214         var code = WNetAddConnection(username, password, remoteName, localName);

215         connectSuccess = code == 0;

216 #if CheckReturn

217 

218         if (code != 0)

219         {

220             GetLastError();

221 

222             throw new InvalidOperationException("The method WNetAddConnection return " + code);

223         }

224 #endif

225     }

226 

227     private static void GetLastError()

228     {

229         uint lpError = 0;

230         string lpErrorBuf = null;

231         uint nErrorBufSize = 1024;

232         string lpNameBuf = null;

233         uint nNameBufSize = 1024;

234         var errCode = WNetGetLastError(ref lpError, ref lpErrorBuf, nErrorBufSize, ref lpNameBuf, nNameBufSize);

235     }

236 

237     public static WNetConnectionHelper New(string username, string password, string remoteName, string localName)

238     {

239         if (string.IsNullOrEmpty(remoteName))

240             throw new ArgumentException("remoteName");

241         return new WNetConnectionHelper(username, password, remoteName.TrimEnd('/'), localName);

242     }

243 

244 

245     #endregion

246 

247     #region IDisposable 成员

248 

249     public void Dispose()

250     {

251         if (!connectSuccess) return;

252         if (string.IsNullOrEmpty(remoteName)) return;

253         var code = Close();

254 #if CheckReturn

255         if (code != 0)

256         {

257             GetLastError();

258             throw new InvalidOperationException("The method WNetCancelConnection return " + code);

259 

260         }

261 #endif

262     }

263 

264     private uint Close()

265     {

266 

267         return WNetCancelConnection(remoteName, 1, true);

268     }

269 

270     #endregion

271 }
View Code

 

你可能感兴趣的:(asp.net)