1

Is there a way in C# to programmly map a network location? (and by maaping a network location, I mean to map it under Computer - in the windows OS you can do it by clicking computer, then right click -> "Map a network location"). Is there a way to do it on C#?

I found a way to map a network drive on C#, which is similiar - but It's getting diffucult with the letters (since I want the option to mapping a large numbers of folders, and not getting confused with letters)

Thanks! :>

HanzoS
  • 21
  • 1
  • 3
  • 1
    Have you seen [this related post](https://stackoverflow.com/q/659013/1911064)? The [NetUseAdd](http://www.pinvoke.net/default.aspx/netapi32/NetUseAdd.html) API should be helpful. – Axel Kemper Apr 11 '19 at 14:39
  • Isn't working for me :( – HanzoS Apr 12 '19 at 17:11

1 Answers1

1

The following works for me:

//  from http://pinvoke.net/default.aspx/mpr/WNetAddConnection2.html
using System.Runtime.InteropServices;

namespace Utilities.Network
{
    public class NetworkDrive
    {
        public enum ResourceScope
        {
            RESOURCE_CONNECTED = 1,
            RESOURCE_GLOBALNET,
            RESOURCE_REMEMBERED,
            RESOURCE_RECENT,
            RESOURCE_CONTEXT
        }

        public enum ResourceType
        {
            RESOURCETYPE_ANY,
            RESOURCETYPE_DISK,
            RESOURCETYPE_PRINT,
            RESOURCETYPE_RESERVED
        }

        public enum ResourceUsage
        {
            RESOURCEUSAGE_CONNECTABLE = 0x00000001,
            RESOURCEUSAGE_CONTAINER = 0x00000002,
            RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
            RESOURCEUSAGE_SIBLING = 0x00000008,
            RESOURCEUSAGE_ATTACHED = 0x00000010,
            RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),
        }

        public 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
        }

        [System.Flags]
        public enum AddConnectionOptions
        {
            CONNECT_UPDATE_PROFILE = 0x00000001,
            CONNECT_UPDATE_RECENT = 0x00000002,
            CONNECT_TEMPORARY = 0x00000004,
            CONNECT_INTERACTIVE = 0x00000008,
            CONNECT_PROMPT = 0x00000010,
            CONNECT_NEED_DRIVE = 0x00000020,
            CONNECT_REFCOUNT = 0x00000040,
            CONNECT_REDIRECT = 0x00000080,
            CONNECT_LOCALDRIVE = 0x00000100,
            CONNECT_CURRENT_MEDIA = 0x00000200,
            CONNECT_DEFERRED = 0x00000400,
            CONNECT_RESERVED = unchecked((int)0xFF000000),
            CONNECT_COMMANDLINE = 0x00000800,
            CONNECT_CMD_SAVECRED = 0x00001000,
            CONNECT_CRED_RESET = 0x00002000
        }

        [StructLayout(LayoutKind.Sequential)]
        private class NETRESOURCE
        {
            public ResourceScope dwScope = 0;
            //  change resource type as required
            public ResourceType dwType = ResourceType.RESOURCETYPE_DISK;
            public ResourceDisplayType dwDisplayType = 0;
            public ResourceUsage dwUsage = 0;
            public string lpLocalName = null;
            public string lpRemoteName = null;
            public string lpComment = null;
            public string lpProvider = null;
        }

        [DllImport("mpr.dll")]
        private static extern int WNetAddConnection2(NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags);

        /// <summary>
        /// Map network drive 'unc' to local Windows drive 'drive'
        /// </summary>
        /// <param name="unc">network path (example: @"\\servername\shardrive")</param>
        /// <param name="drive">local Windows drive (example: "Q:")</param>
        /// <param name="user">username (null, if not specified)</param>
        /// <param name="password">password (null, if not specified)</param>
        /// <returns></returns>
        public static int MapNetworkDrive(string unc, string drive, string user, string password)
        {
            NETRESOURCE myNetResource = new NETRESOURCE();
            myNetResource.lpLocalName = drive;
            myNetResource.lpRemoteName = unc;
            myNetResource.lpProvider = null;
            //  change dwFlags parameter as required
            int result = WNetAddConnection2(myNetResource, password, user, 
                                            (int)AddConnectionOptions.CONNECT_TEMPORARY);
            return result;
        }
    }
}

Example call:

string unc = "https://webdav.xxx.de/";
string drive = "Q:";
string username = "someUser";
string password = "somePassword";

int status =
  Utilities.Network.NetworkDrive.MapNetworkDrive(unc, drive, username, password);

if (status == 0)
{
     Console.WriteLine($"{unc} mapped to drive {drive}");
}
else
{
     //  https://stackoverflow.com/a/1650868/1911064
     string errorMessage = 
         new System.ComponentModel.Win32Exception(status).Message;
     Console.WriteLine($"Failed to map {unc} to drive {drive}!");
     Console.WriteLine(errorMessage);
}

In case, a non-zero status is returned, you might have to tweak parameters.

Axel Kemper
  • 10,544
  • 2
  • 31
  • 54