A
Andrew Raastad
We have a very old COM/Active-X DLL that our web application (non-.Net) uses
to interact with the server, and to map a network drive to the server for
use through the web application. But we need to update this whole method as
this solution won't work as is on 64-Bit servers. While this web app is not
MS technology, it can interact with Web Services, so I thought making a .Net
Web Service would do the trick, but running into a little snag....
The original Com/Active-X DLL had a reference to something called
"WshNetwork". This it turns out is the "Windows Script Host Object Model"
(wshom.ocx).
Making a reference to this via COM Interop, it creates
"Interop.IWshRuntimeLibrary.dll" in the bin folder for me to use in the
application, so I can write some code that is more in line with the original
DLL:
Private Shared Sub MountVolume(ByVal Volume As String, ByVal NetworkPath
As String, ByVal UserName As String, ByVal Password As String)
Dim ws As New IWshRuntimeLibrary.IWshNetwork_Class
Try
If UserName.Length > 0 Then
ws.MapNetworkDrive(Volume, NetworkPath, Nothing,
CObj(UserName), CObj(Password))
Else
ws.MapNetworkDrive(Volume, NetworkPath)
End If
Catch ex As Exception
Throw New Exception(String.Format("MountVolume() Failed:
{0}{1}", vbCrLf, ex.Message))
End Try
End Sub
Private Shared Sub UnMountVolume(ByVal Volume As String, ByVal Force As
Boolean)
Dim ws As New IWshRuntimeLibrary.WshNetwork
Try
ws.RemoveNetworkDrive(Volume, CObj(Force))
Catch ex As Exception
Throw New Exception(String.Format("UnMountVolume() Failed:
{0}{1}", vbCrLf, ex.Message))
End Try
End Sub
And through this Interface I can even get a listing of the current network
drives on the machine:
Public Function GetMappedDrives() As String
Dim ws As New IWshRuntimeLibrary.IWshNetwork_Class
Try
Dim sb As New StringBuilder
Dim colDrives As IWshCollection = ws.EnumNetworkDrives
For i As Integer = 0 To (colDrives.Count - 1) Step 2
sb.Append(String.Format("{0} ", colDrives(i)))
Next
Return sb.ToString.Trim.Replace(" ", ",")
Catch ex As Exception
Throw New Exception(String.Format("GetMappedDrives()
Failed:{0}{1}", vbCrLf, ex.Message))
End Try
End Function
So, I create a new Web Service project and add the above three methods,
exposing each as a public <WebMethod()>. Then, I create a completely
separate win form app that has a "Map Drive" button, an "UnMap Drive"
button, and a "Get Drives" button. I add a reference to the web service and
then tie the three buttons to the respective exposed web methods. Running
the winform app, I click the Map Drive button and sure enough, the network
drive shows up in My Computer. Clicking the UnMap Drive button and the
drive disappears in My Computer. And clicking the Get Drives button gives me
a list of the drive letters that are network drives on my machine.
At this point I'm ecstatic.... I have a Web Service mapping and unmapping
network drives. So, I copy the web service over to my test server (a Win
2003 Server), make a web reference in my winform app to the test server, run
the winform app, and.... *boom*!
When clicking the MapDrive button (which passes "J:" for a drive letter, and
also the UNC path, and my username and password values) I get the following
error:
System.Web.Services.Protocols.SoapException: Server was unable to process
request. ---> System.Exception: MountVolume() Failed: The local device name
is already in use. (Exception from HRESULT: 0x80070055) at
NMSWebServices.Network.MountVolume(String Volume, String NetworkPath, String
UserName, String Password) at NMSWebServices.Network.MapDrive(String
DriveLetter, String UNCPath, String strDomain, String strUsername, String
strPassword) --- End of inner exception stack trace ---
I have double checked, and the drive letter "J:" is *NOT* in use when I run
this, yet the error seems to state the code thinks it is.
If I click the UnMap Drive I get an error telling me there is no such
resource in use, which I would expect, and until I can map a drive I can't
really test this one.
If I click the Get Drives button, I get an empty string back.
So now, it doesn't seem to be a permissions issue, but rather something
else.... but I have no clue what. Normally, typing in the error into Google
would get an answer in short order, but this error isn't helping much at
all.
Anyone have an idea as to what's happening here?
-- Andrew
to interact with the server, and to map a network drive to the server for
use through the web application. But we need to update this whole method as
this solution won't work as is on 64-Bit servers. While this web app is not
MS technology, it can interact with Web Services, so I thought making a .Net
Web Service would do the trick, but running into a little snag....
The original Com/Active-X DLL had a reference to something called
"WshNetwork". This it turns out is the "Windows Script Host Object Model"
(wshom.ocx).
Making a reference to this via COM Interop, it creates
"Interop.IWshRuntimeLibrary.dll" in the bin folder for me to use in the
application, so I can write some code that is more in line with the original
DLL:
Private Shared Sub MountVolume(ByVal Volume As String, ByVal NetworkPath
As String, ByVal UserName As String, ByVal Password As String)
Dim ws As New IWshRuntimeLibrary.IWshNetwork_Class
Try
If UserName.Length > 0 Then
ws.MapNetworkDrive(Volume, NetworkPath, Nothing,
CObj(UserName), CObj(Password))
Else
ws.MapNetworkDrive(Volume, NetworkPath)
End If
Catch ex As Exception
Throw New Exception(String.Format("MountVolume() Failed:
{0}{1}", vbCrLf, ex.Message))
End Try
End Sub
Private Shared Sub UnMountVolume(ByVal Volume As String, ByVal Force As
Boolean)
Dim ws As New IWshRuntimeLibrary.WshNetwork
Try
ws.RemoveNetworkDrive(Volume, CObj(Force))
Catch ex As Exception
Throw New Exception(String.Format("UnMountVolume() Failed:
{0}{1}", vbCrLf, ex.Message))
End Try
End Sub
And through this Interface I can even get a listing of the current network
drives on the machine:
Public Function GetMappedDrives() As String
Dim ws As New IWshRuntimeLibrary.IWshNetwork_Class
Try
Dim sb As New StringBuilder
Dim colDrives As IWshCollection = ws.EnumNetworkDrives
For i As Integer = 0 To (colDrives.Count - 1) Step 2
sb.Append(String.Format("{0} ", colDrives(i)))
Next
Return sb.ToString.Trim.Replace(" ", ",")
Catch ex As Exception
Throw New Exception(String.Format("GetMappedDrives()
Failed:{0}{1}", vbCrLf, ex.Message))
End Try
End Function
So, I create a new Web Service project and add the above three methods,
exposing each as a public <WebMethod()>. Then, I create a completely
separate win form app that has a "Map Drive" button, an "UnMap Drive"
button, and a "Get Drives" button. I add a reference to the web service and
then tie the three buttons to the respective exposed web methods. Running
the winform app, I click the Map Drive button and sure enough, the network
drive shows up in My Computer. Clicking the UnMap Drive button and the
drive disappears in My Computer. And clicking the Get Drives button gives me
a list of the drive letters that are network drives on my machine.
At this point I'm ecstatic.... I have a Web Service mapping and unmapping
network drives. So, I copy the web service over to my test server (a Win
2003 Server), make a web reference in my winform app to the test server, run
the winform app, and.... *boom*!
When clicking the MapDrive button (which passes "J:" for a drive letter, and
also the UNC path, and my username and password values) I get the following
error:
System.Web.Services.Protocols.SoapException: Server was unable to process
request. ---> System.Exception: MountVolume() Failed: The local device name
is already in use. (Exception from HRESULT: 0x80070055) at
NMSWebServices.Network.MountVolume(String Volume, String NetworkPath, String
UserName, String Password) at NMSWebServices.Network.MapDrive(String
DriveLetter, String UNCPath, String strDomain, String strUsername, String
strPassword) --- End of inner exception stack trace ---
I have double checked, and the drive letter "J:" is *NOT* in use when I run
this, yet the error seems to state the code thinks it is.
If I click the UnMap Drive I get an error telling me there is no such
resource in use, which I would expect, and until I can map a drive I can't
really test this one.
If I click the Get Drives button, I get an empty string back.
So now, it doesn't seem to be a permissions issue, but rather something
else.... but I have no clue what. Normally, typing in the error into Google
would get an answer in short order, but this error isn't helping much at
all.
Anyone have an idea as to what's happening here?
-- Andrew