IIS/ASP.NET访问共享文件夹的可用方式
【截止2014-10-14】
网上搜索了很多篇文章,所提及的总共有两种方式:
1.Asp.Net模拟登陆;
例如:
实战ASP.NET访问共享文件夹(含详细操作步骤)
实现一个2008serve的IIS的虚拟目录(通过网络路径(UNC)的形式,共享在另外一个2008服务器上
2.调用Windows API 的 WNetAddConnection2 、WNetCancelConnection2函数;
例如:
ASP.NET网络映射驱动器无权限访问的解决方案
ASP.NET访问网络驱动器(映射磁盘)
相对来说,第一种方式是最直接的,且改动较小的。但不足之处就是比较依赖共享所在服务器(如果切换共享服务器地址,那么本地的用户名和密码都要作调整。);
而第二种方式缺点(个人感觉),API函数的不稳定、链接数超出限制、内存泄露等不稳定的问题(如果有哪位朋友有解决方案,还请告知,谢谢)。
ps:折腾了两天,先用第一种方式吧。附上一个第二种方式的辅助类。
#define CheckReturn
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; /// <summary>
/// 网络资源访问
/// </summary>
public class WNetConnectionHelper : IDisposable
{ /// <summary>
/// 添加远程网络连接。
/// </summary>
/// <param name="lpNetResource">是一个包含网络访问资源的结构,在这里作为参数用来指定详细的网络连接信息</param>
/// <param name="lpPassword">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
/// <param name="lpUsername">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
/// <param name="dwFlags">指出连接选项,包含六种设置</param>
/// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
[DllImport("Mpr.dll", EntryPoint = "WNetAddConnection2")]
/*
private static extern uint WNetAddConnection2(NetResource lpNetResource, [MarshalAs(UnmanagedType.LPStr)]string lpPassword, [MarshalAs(UnmanagedType.LPStr)]string lpUsername, uint dwFlags);
*/
private static extern uint WNetAddConnection2(IntPtr lpNetResource, string lpPassword, string lpUsername, uint dwFlags); /// <summary>
/// 释放存在的网络连接。
/// </summary>
/// <param name="lpName">指定本地驱动器或远程共享资源</param>
/// <param name="dwFlags">表示断开连接方式。设置 0 或CONNECT_UPDATE_PROFILE。</param>
/// <param name="fForce">如果当前正在使用远程资源,是否进行强制断开连接。如果设置FALSE,在有远程资源使用的情况下关闭连接操作将会失败。</param>
/// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
[DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")]
private static extern uint WNetCancelConnection2([MarshalAs(UnmanagedType.LPStr)]string lpName, uint dwFlags, int fForce); /// <summary>
/// 获取网络错误的扩展错误信息
/// </summary>
/// <param name="lpError">指定一个变量,用于装载网络错误代码。具体的代码由网络供应商决定</param>
/// <param name="lpErrorBuf">指定一个字串缓冲区,用于装载网络错误的说明</param>
/// <param name="nErrorBufSize">lpErrorBuf缓冲区包含的字符数量</param>
/// <param name="lpNameBuf">用于装载网络供应商名字的字串缓冲区</param>
/// <param name="nNameBufSize">lpNameBuf缓冲区的字符数量</param>
/// <returns></returns>
[DllImport("Mpr.dll", EntryPoint = "WNetGetLastError")]
private static extern uint WNetGetLastError(ref uint lpError, [MarshalAs(UnmanagedType.LPStr)]ref string lpErrorBuf, long nErrorBufSize, [MarshalAs(UnmanagedType.LPStr)]ref string lpNameBuf, uint nNameBufSize); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = )]
public struct NetResource
{
/// <summary>
/// 指定枚举范围。设置RESOURCE_CONNECTED,RESOURCE_GLOBALNET,RESOURCE_REMEMBERED三值之一。
/// </summary>
public int dwScope;
/// <summary>
/// 指定访问的资源类型。设置三个值之一。RESOURCETYPE_ANY表示所有资源;RESOURCETYPE_DISK表示磁盘资源;RESOURCETYPE_PRINT表示打印机。
/// </summary>
public int dwType;
/// <summary>
/// 指出资源显示类型。RESOURCEDISPLAYTYPE_DOMAIN;RESOURCEDISPLAYTYPE_SERVER;RESOURCEDISPLAYTYPE_SHARE;RESOURCEDISPLAYTYPE_GENERIC。
/// </summary>
public int dwDisplayType;
/// <summary>
/// 描述资源的使用方式。设置RESOURCEUSAGE_CONNECTABLE 或RESOURCEUSAGE_CONTAINER。
/// </summary>
public int dwUsage;
/// <summary>
/// 同dwScope关联,指定本地映射。
/// </summary>
//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpLocalName;
/// <summary>
/// 远程访问文件夹路径。
/// </summary>
//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpRemoteName;
/// <summary>
/// 描述。
/// </summary>
//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpComment;
/// <summary>
/// 资源提供者,可以设置为NULL。
/// </summary>
//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpProvider;
} public enum RESOURCE_SCOPE
{
RESOURCE_CONNECTED = ,
RESOURCE_GLOBALNET = ,
RESOURCE_REMEMBERED = ,
RESOURCE_RECENT = ,
RESOURCE_CONTEXT =
} public enum RESOURCE_TYPE
{
RESOURCETYPE_ANY = ,
RESOURCETYPE_DISK = ,
RESOURCETYPE_PRINT = ,
RESOURCETYPE_RESERVED = ,
} public enum RESOURCE_USAGE
{
RESOURCEUSAGE_CONNECTABLE = ,
RESOURCEUSAGE_CONTAINER = ,
RESOURCEUSAGE_NOLOCALDEVICE = ,
RESOURCEUSAGE_SIBLING = ,
RESOURCEUSAGE_ATTACHED = ,
RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),
} public enum RESOURCE_DISPLAYTYPE
{
RESOURCEDISPLAYTYPE_GENERIC = ,
RESOURCEDISPLAYTYPE_DOMAIN = ,
RESOURCEDISPLAYTYPE_SERVER = ,
RESOURCEDISPLAYTYPE_SHARE = ,
RESOURCEDISPLAYTYPE_FILE = ,
RESOURCEDISPLAYTYPE_GROUP = ,
RESOURCEDISPLAYTYPE_NETWORK = ,
RESOURCEDISPLAYTYPE_ROOT = ,
RESOURCEDISPLAYTYPE_SHAREADMIN = ,
RESOURCEDISPLAYTYPE_DIRECTORY = ,
RESOURCEDISPLAYTYPE_TREE = ,
RESOURCEDISPLAYTYPE_NDSCONTAINER =
} /// <summary>
/// 添加远程网络连接。
/// </summary>
/// <param name="netResource">是一个包含网络访问资源的结构,在这里作为参数用来指定详细的网络连接信息</param>
/// <param name="username">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
/// <param name="password">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
/// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
public static uint WNetAddConnection(NetResource netResource, string username, string password)
{
IntPtr ptr_netResource = IntPtr.Zero;
try
{
//分配内存
ptr_netResource = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(netResource));
System.Runtime.InteropServices.Marshal.StructureToPtr(netResource, ptr_netResource, false); uint result = WNetAddConnection2(ptr_netResource, password, username, );
return result;
}
finally
{
if (ptr_netResource != IntPtr.Zero)
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(ptr_netResource);
}
/*
uint result = WNetAddConnection2(netResource, password, username, 0);
return result;
*/
} /// <summary>
/// 添加远程网络连接。
/// </summary>
/// <param name="username">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
/// <param name="password">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
/// <param name="remoteName">远程访问文件夹路径。</param>
/// <param name="localName">同dwScope关联,指定本地映射。</param>
/// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
public static uint WNetAddConnection(string username, string password, string remoteName, string localName)
{
NetResource netResource = new NetResource();
netResource.dwScope = ; //RESOURCE_GLOBALNET
netResource.dwType = ; //RESOURCETYPE_DISK
netResource.dwDisplayType = ; //RESOURCEDISPLAYTYPE_SHARE
netResource.dwUsage = ; //RESOURCEUSAGE_CONNECTABLE
netResource.lpLocalName = localName;
netResource.lpRemoteName = remoteName.TrimEnd('/');
//netResource.lpRemoteName = lpComment;
//netResource.lpProvider = null;
uint result = WNetAddConnection(netResource, username, password);
return result;
} /// <summary>
/// 添加远程网络连接。
/// </summary>
/// <param name="name">指定本地驱动器或远程共享资源</param>
/// <param name="flags">表示断开连接方式。设置 0 或CONNECT_UPDATE_PROFILE。</param>
/// <param name="force">如果当前正在使用远程资源,是否进行强制断开连接。如果设置FALSE,在有远程资源使用的情况下关闭连接操作将会失败。</param>
/// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
public static uint WNetCancelConnection(string name, uint flags, bool force)
{
uint nret = WNetCancelConnection2(name, flags, force ? : );
return nret;
} #region SelfUsing
bool connectSuccess = false;
string username, password, remoteName, localName;
private WNetConnectionHelper(string username, string password, string remoteName, string localName)
{
this.username = username;
this.password = password;
this.remoteName = remoteName;
this.localName = localName;
Close();
var code = WNetAddConnection(username, password, remoteName, localName);
connectSuccess = code == ;
#if CheckReturn if (code != )
{
GetLastError(); throw new InvalidOperationException("The method WNetAddConnection return " + code);
}
#endif
} private static void GetLastError()
{
uint lpError = ;
string lpErrorBuf = null;
uint nErrorBufSize = ;
string lpNameBuf = null;
uint nNameBufSize = ;
var errCode = WNetGetLastError(ref lpError, ref lpErrorBuf, nErrorBufSize, ref lpNameBuf, nNameBufSize);
} public static WNetConnectionHelper New(string username, string password, string remoteName, string localName)
{
if (string.IsNullOrEmpty(remoteName))
throw new ArgumentException("remoteName");
return new WNetConnectionHelper(username, password, remoteName.TrimEnd('/'), localName);
} #endregion #region IDisposable 成员 public void Dispose()
{
if (!connectSuccess) return;
if (string.IsNullOrEmpty(remoteName)) return;
var code = Close();
#if CheckReturn
if (code != )
{
GetLastError();
throw new InvalidOperationException("The method WNetCancelConnection return " + code); }
#endif
} private uint Close()
{ return WNetCancelConnection(remoteName, , true);
} #endregion
}
IIS/ASP.NET访问共享文件夹的可用方式的更多相关文章
- 实战ASP.NET访问共享文件夹(含详细操作步骤)
博客园找找看(http://zzk.cnblogs.com)的索引文件占用空间太大,需要移至另外一台服务器,所以要解决"在ASP.NET中通过共享文件夹访问索引文件"的问题. 假设 ...
- ASP.NET 访问共享文件夹
配置代码: var dataProtection = new Microsoft.AspNet.DataProtection.DataProtectionProvider(new DirectoryI ...
- (转)WIN7更改用户名访问共享文件夹
原文地址: http://ryy8013.blog.163.com/blog/static/71729589201210610533778/ 一直以来,windows7客户端访问windows ser ...
- PC问题-可以PING通IP,PING名字不通,可以远程,但不能访问共享文件夹?
问题现象:可以PING通IP,PING名字不通,可以远程,但不能访问共享文件夹? 问题原因:目标主机中NetLogon服务未启动. 问题处理:远程打开目标主机,“我的电脑-管理-服务-启动(改为自动) ...
- VirtualBox中的Ubuntu没有权限访问共享文件夹/media/sf_bak
之前已经搞定可以自动共享文件夹了,但是现在发现无法去访问,非root用户下,使用“ls /media/sf_bak”提示没有权限,当然如果切换到root,是可以的. [解决过程]1.把普通用户名加入到 ...
- 清除在Windows下访问共享文件夹时的登录信息
清除在Windows下访问共享文件夹时的登录信息 在实际工作中,经常需要访问局域网内其他机子上的共享文件夹,例如\\192.168.1.100\d$ , 首次访问时,需要输入用户名和密码才可以进入,即 ...
- IIS Asp.Net 访问 Com组件 报拒绝访问
IIS Asp.Net 访问 Com组件 报拒绝访问 解决方法: IIS 程序池->高级设置->进程模式->标识->内置帐户=LocalSystem
- [转]Win10企业版无法访问共享文件夹
Win10系统电脑在更新后,当我们访问共享文件夹时可能会出现如下图所示窗口,导致我们无法访问.那么这个问题如何解决呢?具体如下:1. 首先我们按“Windows+R键”打开运行窗口.2. 在该窗口文本 ...
- 第一篇-ubuntu18.04访问共享文件夹
1. 在访问Windows共享资料之前,请确保Windows共享是可用的.Linux访问Windows共享或者LInux共享资料给Windows时,都使用Samba软件 rpm -qa | grep ...
随机推荐
- USACO The Clocks
操作间没有次序关系,同一个操作最多重复3次... 可以直接暴力... The Clocks IOI'94 - Day 2 Consider nine clocks arranged in a 3x3 ...
- 布式实时日志系统(三) 环境搭建之centos 6.4下hadoop 2.5.2完全分布式集群搭建最全资料
最近公司业务数据量越来越大,以前的基于消息队列的日志系统越来越难以满足目前的业务量,表现为消息积压,日志延迟,日志存储日期过短,所以,我们开始着手要重新设计这块,业界已经有了比较成熟的流程,即基于流式 ...
- 【WEB前端系列之CSS】CSS3动画之Transform
前言 Transform字面上是变形,改变的意思,在CSS3中transform主要包括如下几种 旋转rotate 扭曲skew 缩放scale 移动translate 矩形变形matrix tran ...
- [转]F5负载均衡算法及基本原理
原文:Intro to Load Balancing for Developers – The Algorithms 转载:http://blog.gesha.net/archives/205/ p ...
- 如何设置select只读不可编辑且select的值可传递
1. <select style="width:195px" name="role" id="role" onfocus=" ...
- 剑指offer题目记录
1.如下为类型CMyString的声明,请为该类型添加赋值运算符函数. class CMyString { public: CMyString(char* pData = NULL); CMyStri ...
- Dockerfile创建镜像
Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像. Dockerfile由一行行命令语句组成,并且支持易#开头的注释行. 一般而言Dockerfil ...
- DXP 内电层分割
多层电路板中间层设置与内电层如何分割 多层电路板与一般的电路板不同之处在于,多层电路板除了顶层和底层之外,还有若干中间层,这些中间层可以是信号层(mid layer),也可以是内部电源/接地层(int ...
- 【CF878E】Numbers on the blackboard 并查集
[CF878E]Numbers on the blackboard 题意:给你一个长度为n个数列,你每次可以进行如下操作: 选取两个相邻的数x,y(x在y左面),然后将这两个数去掉,用x+2y替换它. ...
- Android加载asset的db
extends:http://blog.csdn.net/lihenair/article/details/21232887 项目需要将预先处理的db文件加载到数据库中,然后读取其中的信息并显示 加载 ...