Re: Mapping a network drive
Oh and here's a bonus - how to delete an existing mapped drive :D
API Definitions:
vb Code:
Public Const CONNECT_UPDATE_PROFILE As UInteger = 1
Public Const NO_ERROR As UInteger = 0
''' <summary>
''' Deletes a connection to a network resource
''' </summary>
''' <param name="lpName">The name of the connection to delete (e.g drive letter)</param>
''' <param name="dwFlags">If this is a persistent connection set to CONNECT_UPDATE_PROFILE to prevent from being mapped again at next logon</param>
''' <param name="fForce">Delete connection even if files from this resource are still open</param>
<DllImportAttribute("mpr.dll", EntryPoint:="WNetCancelConnectionW")> _
Public Shared Function WNetCancelConnection(<InAttribute(), MarshalAsAttribute(UnmanagedType.LPWStr)> ByVal lpName As String, ByVal dwFlags As UInteger, <MarshalAsAttribute(UnmanagedType.Bool)> ByVal fForce As Boolean) As UInteger
End Function
and my .NET method that wraps up the API functionality:
vb Code:
''' <summary>
''' Deletes an existing mapped network drive
''' </summary>
''' <param name="DriveLetter">The drive letter to delete, must be a network drive</param>
''' <param name="Force">Force the drive to be deleted even if files are still open on this drive</param>
Public Shared Sub RemoveNetworkDrive(ByVal DriveLetter As Char, ByVal Force As Boolean)
Dim Result As UInteger = WNetCancelConnection(DriveLetter & ":", CONNECT_UPDATE_PROFILE, Force)
If Not Result = NO_ERROR Then
Throw New System.ComponentModel.Win32Exception(CInt(Result))
End If
End Sub
So once you have copied and pasted all that into your project you can do this to delete a mapped drive:
vb Code:
'Deletes the F drive
'Throws an exception if F is not a network drive
RemoveNetworkDrive("F"c, True)
Re: Mapping a network drive
this has been very useful to me, thx ! =)
Re: Mapping a network drive
No worries, glad it was helpful :)
Re: Mapping a network drive
Sorry to revive... but I tried this out. The mapping works great so far but the delete is having issues.
First this line: Public Const NO_ERROR as UInteger = 0 is coming up as a problem saying its already declared in this class.
So I commented that out.
Then when I try to delete a mapped drive it will cause issues and lock up.
This is what I get.
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'blahblah::WNetCancelConnection' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
Any help with this would be nice. If we can't figure it out im sure i can delete mapped drives some other way.
Re: Mapping a network drive
Well yeah the constant NO_ERROR is already declared in the first bit of code I posted on how to map a drive, so if you had already copied that and then copied the second part on removing a mapped drive as well then you'll obviously need to delete one of the NO_ERROR declarations.
As for the stack imbalance error, I looked in the latest version of my Windows API library and this is how I've got it declared now (notice the entry point is WNetCancelConnection2W not WNetCancelConnectionW like in my original post):
Code:
''' <summary>
''' Deletes a connection to a network resource
''' </summary>
''' <param name="lpName">The name of the connection to delete (e.g drive letter)</param>
''' <param name="dwFlags">If this is a persistent connection set to CONNECT_UPDATE_PROFILE to prevent from being mapped again at next logon</param>
''' <param name="fForce">Delete connection even if files from this resource are still open</param>
<DllImport("mpr.dll", EntryPoint:="WNetCancelConnection2W", SetLastError:=True)> _
Public Shared Function WNetCancelConnection(<InAttribute(), MarshalAsAttribute(UnmanagedType.LPWStr)> ByVal lpName As String, ByVal dwFlags As UInteger, <MarshalAsAttribute(UnmanagedType.Bool)> ByVal fForce As Boolean) As UInteger
End Function
and then to use it:
Code:
''' <summary>
''' Deletes an existing mapped network drive
''' </summary>
''' <param name="DriveLetter">The drive letter to delete, must be a network drive</param>
''' <param name="Force">Force the drive to be deleted even if files are still open on this drive</param>
Public Shared Sub RemoveNetworkDrive(ByVal DriveLetter As Char, ByVal Force As Boolean)
Dim Result As UInteger = WNetCancelConnection(DriveLetter & ":", CONNECT_UPDATE_PROFILE, Force)
If Not Result = NO_ERROR Then
Throw New System.ComponentModel.Win32Exception(CInt(Result))
End If
End Sub
If you want to skip having to define these things yourself etc you can just download the DLL I wrote that has all of these API definitions and .NET wrapper methods in it from my blog: http://blog.cjwdev.co.uk/2011/06/12/...-2-2-released/
Re: Mapping a network drive
Thank you, I took the old code out and put these both in.
Now i get another error but its only when the drive it expects to be mapped is not mapped.
I am guessing it has something to do with that no_error thing i commented out before.
It happens in the second chunk of code at the "throw new system.componentmode1.win32exception(CInt(result)) line.
The error says, A first chance exception of type 'system.componentmodel.win32exception' occurred.
It also says, This network connection does not exist.
Re: Mapping a network drive
No that's nothing to do with the NO_ERROR constant, that's an error that is being thrown for exactly the reason it says - you're trying to delete something that doesn't exist. You should loop through the current list of network drives and see if the drive exists before you try and delete it. See example below on how to loop through network drives:
Code:
For Each Drive As IO.DriveInfo In IO.DriveInfo.GetDrives()
If Drive.DriveType = IO.DriveType.Network Then
MessageBox.Show("Drive " & Drive.Name & " is a network drive")
End If
Next
If you wanted to check to see the actual UNC path that a network drive is mapped to you can use another function from my API library DLL that I linked to in the previous post like so:
Code:
MessageBox.Show(Cjwdev.WindowsApi.NativeFileSystem.GetUncPathFromNetworkDrive("H"c))
That example would show you the UNC path that the H drive is mapped to - obviously if you wanted to work with a different drive letter you'd replace H with whatever letter you wanted. The lower case "c" after the letter H is just converting it from a String to a Char as I made that function only accept a single letter as the parameter, so that there was no confusion over how the drive letter should be specified (as it people could think it should be "H" or "H:" or "H:\")
Re: Mapping a network drive
Ok so i just have to do a check it sounds like to make sure the drives i will be using are mapped before trying to delete.
I didnt know if your code already would counter that or not. Sounds good.
Re: Mapping a network drive
I am using your .NET Windows API library, and I am loving it. I ran into a problem, though, when I recently upgraded to Windows 7 64-bit. I get no errors when the MapNetworkDrive function runs, then my "If Drive Exists Then Start Explorer" statement fires and Explorer states the drive doesn't exist.
Is there a 64-bit version of your API library?
Thanks,
Carthax
Re: Mapping a network drive
Quote:
Originally Posted by
Carthax
I am using your .NET Windows API library, and I am loving it. I ran into a problem, though, when I recently upgraded to Windows 7 64-bit. I get no errors when the MapNetworkDrive function runs, then my "If Drive Exists Then Start Explorer" statement fires and Explorer states the drive doesn't exist.
Is there a 64-bit version of your API library?
Thanks,
Carthax
Is your program running "As Administrator" (aka with elevated permissions) ? If so then any drives you map will not be visible to explorer because explorer is running with different permissions. There's a registry entry you can set to change this behaviour but that's how it works by default. Its nothing to do with 64/32 bit and every program has the same issue (try using the Net Use command from an elevated command prompt and you'll have the same issue)
Re: Mapping a network drive
Quote:
Originally Posted by
chris128
Is your program running "As Administrator" (aka with elevated permissions) ? If so then any drives you map will not be visible to explorer because explorer is running with different permissions. There's a registry entry you can set to change this behaviour but that's how it works by default. Its nothing to do with 64/32 bit and every program has the same issue (try using the Net Use command from an elevated command prompt and you'll have the same issue)
Interesting. You're absolutely right. My code requires that the app run as administrator, and it does appear to map the drive as administrator (as expected), but it is running Explorer as a non-elevated user (completely unexpected). Let me see what I can do about that. ...and I wonder how many of the other folks asking about that on Google are having the same problem...? Thanks for the help!
Re: Mapping a network drive
It runs explorer non-elevated because you're not actually launching a new instance of explorer.exe (as that's a single instance application) - if you try to start explorer.exe when one instance of it is already running in your session then it just opens an explorer window from that existing explorer.exe process.
Oh and yes you'll find plenty of results on google about the mapped drives not persisting from elevated apps to non elevated apps