The other day, I had to copy a file from a Windows Service running on our Web server which is outside of our firewall, and not a trusted member of our domain, to a folder on a share inside of the firewall. Should be easy, right? Well, it turns out it that it’s a bit more complicated than I first thought.
In this case I had a username/password in the domain that I could use to access the share from the server. I could successfully map the drive when logged into the console, but my service couldn’t see this mapped drive. My service couldn’t impersonate this trusted domain user either (using LoginUser), since the server itself wasn’t a trusted member of the domain.
There’s no IO managed framework classes for connecting to a network share as a user, and there’s no way to connect to a network share, passing a domain\username and password, AFAIK.
I found out through a lot of searching that I needed to make a call to the WNetAddConnection APIs (mpr.dll) that would allow me to map a drive as a domain user in code. I also have to run my service under the NETWORK_SERVICE account, so that it has access to network resources.
Luckily, I found an article on Code Project Map Network Drive (API) that does exactly this. So, my final solution (simplified), using the NetworkDrive class from the article looks like this:
// Create a network mapped drive
NetworkDrive drive = new NetworkDrive();
drive.ShareName = @”\\SOME_SERVER\SOME_SHARE”;
drive.LocalDrive = “I”;
drive.Force = true;
TextWriter textWriter = File.CreateText(@”I:\file.txt”);
This works really well. The only problem may come up is that if the drive is mapped by some other application, forcing this mapping may cause problems. You could have some code that loops through drive letters until it finds one suitable.