Reputation: 1315
I'm trying to create a windows service in C# that will copy all the files from a network drive and paste it into a local drive (let's say in C drive). When I run the test case, the program runs successfully but when I install and run the windows service, the 'Access is denied' error comes in the log file.
I tried Map Network Drive (API) solution but that solution didn't work. either.
Here's the sample code that I've used to get all the files from a network drive and paste it into the local drive folder
Service1.cs
public partial class Service1 : ServiceBase
{
private Timer _timer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
DoWork();
}
catch (Exception e)
{
WriteErrorLog(e);
}
}
private void DoWork()
{
_timer = new Timer();
_timer.Interval = 5000;
_timer.Enabled = true;
_timer.Elapsed += _timer_Elapsed;
Update();
}
private void Update()
{
RevidAddinController.Update_AutodeskAddinFolder_With_ArchcorpUpdatedAddinFiles(Configuration.AutodeskVersion, Configuration.AutodeskRevitAddinFolderPath);
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Update();
}
private void WriteErrorLog(Exception ex)
{
StreamWriter sw = null;
try
{
sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\Logfile.txt", true);
sw.WriteLine(DateTime.Now.ToString() + " ; " + ex.Source.ToString().Trim() + "; " + ex.Message.ToString().Trim());
sw.Flush();
sw.Close();
}
catch
{
}
}
protected override void OnStop()
{
}
}
RevidAddinController.cs
public static class RevidAddinController
{
public static IEnumerable<AddinStatus> Update_AutodeskAddinFolder_With_ArchcorpUpdatedAddinFiles(List<string> autoDeskVersion, string addinInstallationPath)
{
var networkDrive = ActivateNetworkDrive();
var allAutodeskVersionPath = Util.GetAllAutodeskAddinLibraryFolderPaths(autoDeskVersion, addinInstallationPath);
List<FileData> latestArchcorpAddins = new List<FileData>();
foreach (var autodeskAddinFolder in allAutodeskVersionPath)
{
var archorpAddinFiles = Util.GetAllExternalRevitAddinFilesFromArchcorpAddinFolderPath(Configuration.ArchcorpAddinFolderPath);
var autodeskAddinFiles = Util.GetAllExternalRevitAddinFilesLocationFromAutodeskAddinFolderPath(autodeskAddinFolder);
var latestAddins = Util.GetUpdatedRevitAddinFromArchcorpFolderPath(autodeskAddinFolder, archorpAddinFiles, autodeskAddinFiles)
.Where(addin => !addin.FileName.Contains(Configuration.DeleteAddinNamePrefix));
latestArchcorpAddins.AddRange(latestAddins);
}
List<AddinStatus> addinCopyStatus = new List<AddinStatus>();
foreach (var autodeskAddinPath in allAutodeskVersionPath)
{
foreach (var newArchcorpAddin in latestArchcorpAddins)
{
addinCopyStatus.Add(Util.InstallNewAddinFile(newArchcorpAddin, autodeskAddinPath));
}
}
return addinCopyStatus;
}
/// <summary>
/// Map the network drive path
/// </summary>
/// <returns></returns>
public static NetworkDrive ActivateNetworkDrive()
{
NetworkDrive oNetDrive = new aejw.Network.NetworkDrive();
try
{
oNetDrive.LocalDrive = "O:";
oNetDrive.ShareName = @"\\acdxbfs1\Organisation";
oNetDrive.Force = true;
oNetDrive.Persistent = true;
oNetDrive.MapDrive();
}
catch (Exception err)
{
throw err;
}
return oNetDrive;
}
}
The complete code can be found on the gist here. Would really appreciate if someone reviews the code and provides any feedback/solution to this problem.
Upvotes: 2
Views: 9846
Reputation: 81
If the network file is shared with the local system account then you need to Log In as "Local System Account",
The advantage of running your services as the "Local System account" is that the service has complete unrestricted access to local resources.
But there are some disadvantages also, so be careful to not install unauthorized services as service gets full unrestricted access. Also if the service has some bugs it may lead to performance issues.
Upvotes: 0
Reputation: 1062
The service does run as Local System (as previously named). If you have a mapped network drive to a local drive letter, the service cannot use it (because a mapped network drive is always only mapped for the user context, not the whole computer/system). However the service can access the share by UNC \\server\share. You can view the UNC path if you only have a mapped network drive by typing 'net use' inside a command prompt.
If you run your program as a user Windows does automatically authenticate you at the remote share (if not already done by adding a mapped network drive). Therefor Local System is the computer account you need to set the access permissions of the target share to the computername eg workstation1$ (only available inside a domain cause a workgroup does not know the other computers). This has to be done for the file permissions and the share permissions because both are independent and can restrict you from the access.
As an alternative you can authenticate at the remote network share with an user and password - there is an excellent thread in stackoverflow which you can find here which does show how you can achieve this.
Naturally you can also set the service to a user/password in the services manager (services.msc - double click your service and go to the logon tab) who has access to the share. By doing this, the user will be granted the 'login as service' permission which is necessary for this.
Upvotes: 3
Reputation: 81573
Running a service under the default Local System Account, will have no concept of the share. These are set up under user accounts.
Your 2 options
Upvotes: 3