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

转载:http://blog.csdn.net/zhzuo/article/details/1732937

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

发布日期:2007-08-08 | 更新日期:2009-03-15

作者:郑佐

摘要:本文简单介绍在.NET中如何通过API实现局域网共享访问编程。

本页内容

概述

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.

时间: 2024-10-28 21:28:55

共享访问在.NET中的编程实现的相关文章

在C语言中以编程的方式获取函数名

调试常用的 __FILE__, __FUNCTION__, __LINE__ 调试常用的 __FILE__, __FUNCTION__, __LINE__ 没想到 VC6 不支持 __FUNCTION__ 所以我写了如下的奇怪代码 //用来记录当前行和当前函数//也可说是记录 堆栈void log_stack(const char *file, int line, const char * function); //当然还要对 __FUNCTION__ 宏作点修饰,因为这个宏只是在函数里面才起作

OC中并发编程的相关API和面临的挑战

OC中并发编程的相关API和面临的挑战(1) 小引 http://www.objc.io/站点主要以杂志的形式,深入挖掘在OC中的最佳编程实践和高级技术,每个月探讨一个主题,每个主题都会有几篇相关的文章出炉,2013年7月份的主题是并发编程,今天挑选其中的第2篇文章(Concurrent Programming: APIs and Challenges)进行翻译,与大家分享一下主要内容.由于内容比较多,我将分两部分翻译(API和难点)完成,翻译中,如有错误,还请指正. 目录 1.介绍 2.OS

jQuery中的编程范式

浏览器前端编程的面貌自2005年以来已经发生了深刻的变化,这并不简单的意味着出现了大量功能丰富的基础库,使得我们可以更加方便的编写业务代码,更重要的是我们看待前端技术的观念发生了重大转变,明确意识到了如何以前端特有的方式释放程序员的生产力.本文将结合jQuery源码的实现原理,对javascript中涌现出的编程范式和常用技巧作一简单介绍.    1. AJAX: 状态驻留,异步更新      首先来看一点历史. A. 1995年Netscape公司的Brendan Eich开发了javacri

数据访问工具 DAF 中 ResourceIDService 服务的接口 设计与实现

http://www.paper.edu.cn- 1 -数据访问工具 DAF 中 ResourceIDService 服务的接口设计与实现服务的接口设计与实现陶昕,高锦标华东交通大学信息工程学院,南昌(330013)E-mail:[email protected]摘 要:ResourceID 是 64 位整型数据,是用来定位能量系统中唯一性资源的标识,ResourceIDService 服务是 Data Access Facility 规范简称为 DAF 中的一个重要服务接口,提供了 Resou

C#中面向对象编程机制之多态学习笔记

C#的多态性: 我的理解是:同一个操作,作用于不同的对象时,会有不同的结果,即同一个方法根据需要,作用于不同的对象时,会有不同的实现. C#的多态包括:接口多态,继承多态. 其中继承多态又包括通过虚拟方法实现的多态和通过抽象方法实现的多态性 例如:基类动物都有吃的方法,但是不同的动物吃的东西就会不一样,例如狼吃肉,羊吃草,这样"吃"的这个方法就要在派生类里面重新实现以下,运行时,通过指向基类的指针,来调用实现派生类中的方法. 接下来举例实现多态性. 1. 接口多态性 把动物"

干货 | 玩转云文件存储——利用CFS实现web应用的共享访问

京东云文件服务(Cloud File Service,以下简称:CFS)是一种高可靠.可扩展.可共享访问的全托管分布式文件系统.它可在不中断应用服务的情况下,根据您对文件系统的使用,按需扩展或缩减,并按照实际用量计费.采用NFS协议,支持POSIX文件接口,可为Linux系统下的云主机提供共享访问服务. 演示示意图: 一.创建云主机 打开京东云控制台,依次点击左侧导航弹性计算-云主机,在与云文件服务相同的地域华北-北京创建2台云主机,配置如下: 付费类型:按配置 地域与可用区:华北-北京/可用区

ActionScript3.0教你在影片剪辑中访问主场景中的变量

在ActionScript2.0中,影片剪辑访问主场景中的变量非常的简单,仅仅需要用一个带有_root的绝对路径即可. 然而在ActionScript3.0影片剪辑中访问主场景中的变量却没有那么容易,使用root将会报错.下面为大家介绍一种非常简单的方法来访问主场景中的变量. 方法如下: 1.在MC(影片剪辑实例名称)里定义一个变量father:Object; 2.在主场景代码中进行赋值 MC.father = this; 3.在影片剪辑里访问的时候就直接 father.变量名 就行.

Android中多线程编程(四)AsyncTask类的详细解释(附源码)

Android中多线程编程中AsyncTask类的详细解释 1.Android单线程模型 2.耗时操作放在非主线程中执行 Android主线程和子线程之间的通信封装类:AsyncTask类 1.子线程中更新UI 2.封装.简化异步操作. 3.AsyncTask机制:底层是通过线程池来工作的,当一个线程没有执行完毕,后边的线程是无法执行的.必须等前边的线程执行完毕后,后边的线程才能执行. AsyncTask类使用注意事项: 1.在UI线程中创建AsyncTask的实例 2.必须在UI线程中调用As

《计算机中可编程内存分析》

博主最近刚看了一些斯坦福大学的内存分析课,结合以前做的内存分析, 今天将计算机中可编程的内存做一个分析. 在计算机的可编程内存中,我们一般分为三个区域:静态存储区,栈区,堆区.内存模型如下所示:  静态内存区在程序编译的时候就已经被分配完毕,这块内存在整个计算机内存中位于较低的地址(例如0000),这块内存在整个程序运行期间都存在,静态内存区主要存放的是静态变量.全局变量.常量. 堆区:我们有时候也将堆区称作动态内存区分配区,程序再运行的时候通过new关键字申请得到的任意大小的内存(我们使用ne