WNetAddConnection2 failure exit

patrick

Well-known member
Joined
Dec 5, 2021
Messages
294
Programming Experience
1-3
Hello


If it fails (error), you must disconnect the shared drive and exit.
What should I do?

I Hope Fails Exit:
using (ConnectToSharedFolder con = new ConnectToSharedFolder())
{
     Even though it is a failure (error) WNetAddConnection2, the code below is executed.       
     If it is a failure (error) WNetAddConnection2, you must exit without executing the code here.
}

Call Fails Error:
        var result = WNetAddConnection2(
            netResource,
            credentials.Password,
            userName,
            0);

        if (result != 0)
        {
            // If it is a failure (error) WNetAddConnection2, 
            // you must exit 
            // (public ConnectToSharedFolder(string networkName, NetworkCredential credentials)) 
            // without executing the code here.
        }


Full code:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Net;

public class ConnectToSharedFolder : IDisposable
{
    private readonly string _networkName;

    public ConnectToSharedFolder(string networkName, NetworkCredential credentials)
    {
        _networkName = networkName;

        var netResource = new NetResource
        {
            Scope = ResourceScope.GlobalNetwork,
            ResourceType = ResourceType.Disk,
            DisplayType = ResourceDisplaytype.Share,
            RemoteName = networkName
        };

        var userName = string.IsNullOrEmpty(credentials.Domain)
            ? credentials.UserName
            : $@"{credentials.Domain}\{credentials.UserName}";

        var result = WNetAddConnection2(
            netResource,
            credentials.Password,
            userName,
            0);

        if (result != 0)
        {
            throw new Win32Exception(result, "Error connecting to remote share");
        }
    }

    ~ConnectToSharedFolder()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        WNetCancelConnection2(_networkName, 0, true);
    }

    [DllImport("mpr.dll")]
    private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags);

    [DllImport("mpr.dll")]
    private static extern int WNetCancelConnection2(string name, int flags, bool force);

    [StructLayout(LayoutKind.Sequential)]
    public class NetResource
    {
        public ResourceScope Scope;
        public ResourceType ResourceType;
        public ResourceDisplaytype DisplayType;
        public int Usage;
        public string LocalName;
        public string RemoteName;
        public string Comment;
        public string Provider;
    }

    public enum ResourceScope : int
    {
        Connected = 1,
        GlobalNetwork,
        Remembered,
        Recent,
        Context
    };

    public enum ResourceType : int
    {
        Any = 0,
        Disk = 1,
        Print = 2,
        Reserved = 8,
    }

    public enum ResourceDisplaytype : int
    {
        Generic = 0x0,
        Domain = 0x01,
        Server = 0x02,
        Share = 0x03,
        File = 0x04,
        Group = 0x05,
        Network = 0x06,
        Root = 0x07,
        Shareadmin = 0x08,
        Directory = 0x09,
        Tree = 0x0a,
        Ndscontainer = 0x0b
    }
}
 
Last edited:
Are you sure it executes the code within the using block when the constructor throws an exception on line 34 of the full code? In my experience, it doesn't execute the code within the using block.

The only time I have seen something that looks like the block is executed is because I accidentally had a semicolon at the end of the using line. What I actually had was an empty block, followed by an inner scope of code. The empty block was correctly not executed, and the inner scope that followed it was executed.
 
Last edited:
Anyway, you can play with this code in NetFiddle:
C#:
using System;

class TestMe : IDisposable
{
    public TestMe()
    {
        throw new NotImplementedException("I'm not yet ready.");
    }

    public void Dispose()
    {
    }
}

public class Program
{
    public static void Main()
    {
        try
        {
            using(TestMe testMe = new TestMe())
            {
                Console.WriteLine("You can't see me.");
            }
        }

        catch(Exception ex)
        {
            Console.WriteLine("Caught exception: {0}", ex.Message);
        }

        Console.WriteLine("Can you see me now?");
    }
}

and see that it outputs:
Code:
Caught exception: I'm not yet ready.
Can you see me now?
 
Anyway, you can play with this code in NetFiddle:
C#:
using System;

class TestMe : IDisposable
{
    public TestMe()
    {
        throw new NotImplementedException("I'm not yet ready.");
    }

    public void Dispose()
    {
    }
}

public class Program
{
    public static void Main()
    {
        try
        {
            using(TestMe testMe = new TestMe())
            {
                Console.WriteLine("You can't see me.");
            }
        }

        catch(Exception ex)
        {
            Console.WriteLine("Caught exception: {0}", ex.Message);
        }

        Console.WriteLine("Can you see me now?");
    }
}

and see that it outputs:
Code:
Caught exception: I'm not yet ready.
Can you see me now?




I solved it by doing that you taught me.
thank you very much
 

Latest posts

Back
Top Bottom