Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 903|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-3 07:23:57 | 显示全部楼层 |阅读模式

    写在前面:下文介绍的方法在网上是铺天盖地,虽然能连接网络映射的驱动器,但是并不是很稳定,部署环境windows server 2008 r2 企业版 iis7。

    在密码正确的情况下,有时还会出现ERROR_INVALID_PASSWORD = 86的错误,不知道问题处在哪里,如果有那位高人看见,请不吝赐教!谢谢!

    (转自)http://www.cnblogs.com/xiaopang2010/archive/2011/10/09/2204097.html

    参考:http://www.cnblogs.com/dudu/archive/2012/03/27/asp_net_share_folder.html 

    Windows的网络驱动器映射能加网络上的地址映射为本地磁盘(如Z:盘),可以在资源管理器点“映射网络驱动器”或者cmd下输subst命令进行操作;这在许多时候是十分有用的,比如程序要访问其他厂商的存储在文件服务器上的图片、文档等,这时候通过网络映射就在程序中就能向本地文件一样访问网络上其他位置的文件,同时一定程序也简化了编程。

              但在ASP.NET运行在IIS上时,运行的账户是NETWORK SERVICE或AUTHENTICATED USERS的权限,这就导致没有权限访问映射的驱动器,如下面的代码将会出现FileNotFound的异常。

    1 System.Drawing.Image image = System.Drawing.Image.FromFile("Z://1.jpg");
    2 image.Save("c:\\1.jpg");

    这个问题在我一年前就遇到过,当时没有解决,也找了很多网络上的资料,许多都描述不是太清楚,有建虚拟目录,有修改组策略的,有用户模拟的,网络上跟我一样求助的人一大把,后来摸索了下,整理下思路就把这个问题解决了。

              首先,是需要用户模拟的,但不代表可以获取访问网络磁盘的权限。(此处的用户名和密码是IIS所在机器的用户名和密码)

    1 <identity impersonate="true" userName="administrator" password="admin"/>

    然后,需要调用WNetAddConnection2与网络资源建立连接,WNetCancelConnection2A断开连接,WNetAddConnection2的MSDN解释是:The WNetAddConnection2 function makes a connection to a network resource. The function can redirect a local device to the network resource。网络上找得一个NetworkConnection封装类进行P\Invoke调用,贴代码如下:

     

    View Code
      1 public enum ERROR_ID
      2  {
      3      ERROR_SUCCESS = 0,  // Success
      4      ERROR_BUSY = 170,
      5      ERROR_MORE_DATA = 234,
      6      ERROR_NO_BROWSER_SERVERS_FOUND = 6118,
      7      ERROR_INVALID_LEVEL = 124,
      8      ERROR_ACCESS_DENIED = 5,
      9      ERROR_INVALID_PASSWORD = 86,
     10      ERROR_INVALID_PARAMETER = 87,
     11      ERROR_BAD_DEV_TYPE = 66,
     12      ERROR_NOT_ENOUGH_MEMORY = 8,
     13      ERROR_NETWORK_BUSY = 54,
     14      ERROR_BAD_NETPATH = 53,
     15      ERROR_NO_NETWORK = 1222,
     16      ERROR_INVALID_HANDLE_STATE = 1609,
     17      ERROR_EXTENDED_ERROR = 1208,
     18      ERROR_DEVICE_ALREADY_REMEMBERED = 1202,
     19      ERROR_NO_NET_OR_BAD_PATH = 1203
     20  }
     21  
     22  public enum RESOURCE_SCOPE
     23  {
     24      RESOURCE_CONNECTED = 1,
     25      RESOURCE_GLOBALNET = 2,
     26      RESOURCE_REMEMBERED = 3,
     27      RESOURCE_RECENT = 4,
     28      RESOURCE_CONTEXT = 5
     29  }
     30  
     31  public enum RESOURCE_TYPE
     32  {
     33      RESOURCETYPE_ANY = 0,
     34      RESOURCETYPE_DISK = 1,
     35      RESOURCETYPE_PRINT = 2,
     36      RESOURCETYPE_RESERVED = 8,
     37  }
     38  
     39  public enum RESOURCE_USAGE
     40  {
     41      RESOURCEUSAGE_CONNECTABLE = 1,
     42      RESOURCEUSAGE_CONTAINER = 2,
     43      RESOURCEUSAGE_NOLOCALDEVICE = 4,
     44      RESOURCEUSAGE_SIBLING = 8,
     45      RESOURCEUSAGE_ATTACHED = 16,
     46      RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),
     47  }
     48  
     49  public enum RESOURCE_DISPLAYTYPE
     50  {
     51      RESOURCEDISPLAYTYPE_GENERIC = 0,
     52      RESOURCEDISPLAYTYPE_DOMAIN = 1,
     53      RESOURCEDISPLAYTYPE_SERVER = 2,
     54      RESOURCEDISPLAYTYPE_SHARE = 3,
     55      RESOURCEDISPLAYTYPE_FILE = 4,
     56      RESOURCEDISPLAYTYPE_GROUP = 5,
     57      RESOURCEDISPLAYTYPE_NETWORK = 6,
     58      RESOURCEDISPLAYTYPE_ROOT = 7,
     59      RESOURCEDISPLAYTYPE_SHAREADMIN = 8,
     60      RESOURCEDISPLAYTYPE_DIRECTORY = 9,
     61      RESOURCEDISPLAYTYPE_TREE = 10,
     62      RESOURCEDISPLAYTYPE_NDSCONTAINER = 11
     63  }
     64  
     65  [StructLayout(LayoutKind.Sequential)]
     66  public struct NETRESOURCE
     67  {
     68      public RESOURCE_SCOPE dwScope;
     69      public RESOURCE_TYPE dwType;
     70      public RESOURCE_DISPLAYTYPE dwDisplayType;
     71      public RESOURCE_USAGE dwUsage;
     72  
     73      [MarshalAs(UnmanagedType.LPStr)]
     74      public string lpLocalName;
     75  
     76      [MarshalAs(UnmanagedType.LPStr)]
     77      public string lpRemoteName;
     78  
     79      [MarshalAs(UnmanagedType.LPStr)]
     80      public string lpComment;
     81  
     82      [MarshalAs(UnmanagedType.LPStr)]
     83      public string lpProvider;
     84  }
     85  
     86  public class NetworkConnection
     87  {
     88      [DllImport("mpr.dll")]
     89      public static extern int WNetAddConnection2A(NETRESOURCE[] lpNetResource, string lpPassword, string lpUserName, int dwFlags);
     90  
     91      [DllImport("mpr.dll")]
     92      public static extern int WNetCancelConnection2A(string sharename, int dwFlags, int fForce);
     93  
     94      public static int Connect(string remotePath, string localPath, string username, string password)
     95      {
     96          NETRESOURCE[] share_driver = new NETRESOURCE[1];
     97          share_driver[0].dwScope = RESOURCE_SCOPE.RESOURCE_GLOBALNET;
     98          share_driver[0].dwType = RESOURCE_TYPE.RESOURCETYPE_DISK;
     99          share_driver[0].dwDisplayType = RESOURCE_DISPLAYTYPE.RESOURCEDISPLAYTYPE_SHARE;
    100          share_driver[0].dwUsage = RESOURCE_USAGE.RESOURCEUSAGE_CONNECTABLE;
    101          share_driver[0].lpLocalName = localPath;
    102          share_driver[0].lpRemoteName = remotePath;
    103  
    104          Disconnect(localPath);
    105          int ret = WNetAddConnection2A(share_driver, password, username, 1);
    106  
    107          return ret;
    108      }
    109  
    110      public static int Disconnect(string localpath)
    111      {
    112          return WNetCancelConnection2A(localpath, 1, 1);
    113      }
    114  }

     

    最后,就是使用了,其中Connect方法的参数分别为网络地址、本地要映射的磁盘、网络映射账号、网络映射密码

     

    1 string localpath = "Z:";
    2 int status = NetworkConnection.Connect("\\\\192.168.1.111\\share", localpath, @"administrator", "admin");
    3 if (status == (int)ERROR_ID.ERROR_SUCCESS)
    4 {
    5 System.Drawing.Image image = System.Drawing.Image.FromFile("Z://1.jpg");
    6 image.Save("c:\\1.jpg");     
    7 }
    8 NetworkConnection.Disconnect(localpath);

     

    至于为什么要这样,我的理解是直接调用API建立连接可能也没有权限,在此需要模拟一下用户,再建立连接就直接可以访问,相当于ASP.NET运行的账户下做了网络磁盘映射。

    最后 jww 的评论可以很简单,“但是部署后,总是弹出控制台窗口,感觉不是很好”

    我以前项目中有个简单些的办法,不需要模拟用户,只要在Global.asax里加上下面这句话,然后再程序里访问文件路径直接用\\192.168.x.x\Share这种路径去访问,这样就算有人修改网络映射驱动器也不会对程序有影响了,楼主不妨试试
    void Application_Start(object sender, EventArgs e) 
    {
    System.Diagnostics.Process.Start("net.exe", "use \\\\192.168.x.x\\Share \"admin\" /user:\"administrator\"");

    //192.168.x.x:为网络驱动器的ip地址;Share为文件共享名,不是文件名;administrator为网络驱动器的用户名,admin为密码
    }
     
     

     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 21:06 , Processed in 0.054642 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表