【问题标题】:Map network drive programmatically in C# on Windows 10在 Windows 10 上以 C# 编程方式映射网络驱动器
【发布时间】:2017-04-02 21:56:15
【问题描述】:

我按照方法在以下链接中以编程方式映射网络驱动器: Mapping Network Drive using C#

驱动器似乎连接正确,因为我可以在 C# 中查询目录和文件。但我没有在我的电脑上看到驱动器。 我的目标是以编程方式为我的用户映射某些驱动器。 我不想使用批处理/cmd ... Windows 10 是否存在问题,或者此代码仅适用于编程方法。

亲切的问候

代码的使用:

Utility.NetworkDrive.MapNetworkDrive("R", @"\\unc\path");
var dirs = Directory.GetDirectories("R:"); // got many nice directories...
Utility.NetworkDrive.DisconnectNetworkDrive("R", true);

完整代码:

namespace Utility
{
    public class NetworkDrive
    {
        private enum ResourceScope
        {
            RESOURCE_CONNECTED = 1,
            RESOURCE_GLOBALNET,
            RESOURCE_REMEMBERED,
            RESOURCE_RECENT,
            RESOURCE_CONTEXT
        }
        private enum ResourceType
        {
            RESOURCETYPE_ANY,
            RESOURCETYPE_DISK,
            RESOURCETYPE_PRINT,
            RESOURCETYPE_RESERVED
        }
        private enum ResourceUsage
        {
            RESOURCEUSAGE_CONNECTABLE = 0x00000001,
            RESOURCEUSAGE_CONTAINER = 0x00000002,
            RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
            RESOURCEUSAGE_SIBLING = 0x00000008,
            RESOURCEUSAGE_ATTACHED = 0x00000010
        }
        private enum ResourceDisplayType
        {
            RESOURCEDISPLAYTYPE_GENERIC,
            RESOURCEDISPLAYTYPE_DOMAIN,
            RESOURCEDISPLAYTYPE_SERVER,
            RESOURCEDISPLAYTYPE_SHARE,
            RESOURCEDISPLAYTYPE_FILE,
            RESOURCEDISPLAYTYPE_GROUP,
            RESOURCEDISPLAYTYPE_NETWORK,
            RESOURCEDISPLAYTYPE_ROOT,
            RESOURCEDISPLAYTYPE_SHAREADMIN,
            RESOURCEDISPLAYTYPE_DIRECTORY,
            RESOURCEDISPLAYTYPE_TREE,
            RESOURCEDISPLAYTYPE_NDSCONTAINER
        }
        [StructLayout(LayoutKind.Sequential)]
        private struct NETRESOURCE
        {
            public ResourceScope oResourceScope;
            public ResourceType oResourceType;
            public ResourceDisplayType oDisplayType;
            public ResourceUsage oResourceUsage;
            public string sLocalName;
            public string sRemoteName;
            public string sComments;
            public string sProvider;
        }
        [DllImport("mpr.dll")]
        private static extern int WNetAddConnection2
            (ref NETRESOURCE oNetworkResource, string sPassword,
            string sUserName, int iFlags);

        [DllImport("mpr.dll")]
        private static extern int WNetCancelConnection2
            (string sLocalName, uint iFlags, int iForce);

        public static void MapNetworkDrive(string sDriveLetter, string sNetworkPath)
        {
            //Checks if the last character is \ as this causes error on mapping a drive.
            if (sNetworkPath.Substring(sNetworkPath.Length - 1, 1) == @"\")
            {
                sNetworkPath = sNetworkPath.Substring(0, sNetworkPath.Length - 1);
            }

            NETRESOURCE oNetworkResource = new NETRESOURCE()
            {
                oResourceType = ResourceType.RESOURCETYPE_DISK,
                sLocalName = sDriveLetter + ":",
                sRemoteName = sNetworkPath
            };

            //If Drive is already mapped disconnect the current 
            //mapping before adding the new mapping
            if (IsDriveMapped(sDriveLetter))
            {
                DisconnectNetworkDrive(sDriveLetter, true);
            }

            WNetAddConnection2(ref oNetworkResource, null, null, 0);
        }

        public static int DisconnectNetworkDrive(string sDriveLetter, bool bForceDisconnect)
        {
            if (bForceDisconnect)
            {
                return WNetCancelConnection2(sDriveLetter + ":", 0, 1);
            }
            else
            {
                return WNetCancelConnection2(sDriveLetter + ":", 0, 0);
            }
        }

        public static bool IsDriveMapped(string sDriveLetter)
        {
            string[] DriveList = Environment.GetLogicalDrives();
            for (int i = 0; i < DriveList.Length; i++)
            {
                if (sDriveLetter + ":\\" == DriveList[i].ToString())
                {
                    return true;
                }
            }
            return false;
        }

    }

}

【问题讨论】:

  • 你是从哪个进程运行的?
  • 我在VS Debug模式下尝试过,也启动了编译好的exe。全部在我登录的用户帐户下。
  • 您是否尝试过类似的方法? channel9.msdn.com/Forums/TechOff/…
  • 我访问了这个网站。我首先尝试通过进程调用 net use...。输出显示“成功...”用于添加和删除连接。但我没有看到驱动器。然后我什至创建了一个批处理文件并通过 process.start 调用它,结果相同。正输出,以编程方式访问但看不到驱动器。即使我在资源管理器地址栏中输入驱动器:无法找到驱动器...
  • 我正在去办公室的路上,我会在一个小时内提供代码。

标签: c# network-programming


【解决方案1】:

让我的笔记本电脑休息似乎可以解决 Windows 遇到的任何问题。 以下所有三种方法都非常有效。我最喜欢的当然是 C#“唯一”方法。

// Approach 1
Utility.NetworkDrive.MapNetworkDrive("R", @"\\unc\path");
var dirs1 = Directory.GetDirectories("R:");
Utility.NetworkDrive.DisconnectNetworkDrive("R", true);

// Approach 2
DoProcess("net", @"use R: \\unc\path");
var dirs2 = Directory.GetDirectories("R:");
DoProcess("net", "use /D R:");

// Approach 3
DoProcess("cmd", @"/c C:\local\path\to\batch\connect.cmd");
var dirs3 = Directory.GetDirectories("R:");
DoProcess("cmd", @"/c C:\local\path\to\batch\diconnect.cmd");

public static string DoProcess(string cmd, string argv)
{
    Process p = new Process();
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.FileName = cmd;
    p.StartInfo.Arguments = $" {argv}";
    p.StartInfo.CreateNoWindow = true;
    p.Start();
    p.WaitForExit();
    string output = p.StandardOutput.ReadToEnd();
    p.Dispose();

    return output;
}

【讨论】:

    【解决方案2】:

    映射的驱动器可能会非常混乱。问题是它们只为创建它们的“用户”出现。这在 cmets 关于 UAC 和 Run as Administrator 的问题中有所暗示。

    如果您“运行为”任何人,那么驱动器将只为该人显示。

    如果您只担心用户访问权限与提升用户访问权限,则有一个注册表项可以启用此功能: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

    启用LinkedConnections

    请参阅此以获取更多详细信息: https://docs.microsoft.com/en-us/troubleshoot/windows-client/networking/mapped-drives-not-available-from-elevated-command

    【讨论】:

      【解决方案3】:

      如果您使用@Mario 的方法 2 并希望保留驱动器,请删除以下行:

      DoProcess("net", "use /D R:");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多