Не удается получить доступ к сетевому диску во время работы службы Windows
Я пытаюсь создать службу Windows в C#, которая будет копировать все файлы с сетевого диска и вставлять его на локальный диск (скажем, на диске C). Когда я запускаю тестовый пример, программа запускается успешно, но когда я устанавливаю и запускаю службу Windows, в файле журнала появляется ошибка "Доступ запрещен".
Я попробовал решение Map Network Drive (API), но это решение не сработало. или.
Вот пример кода, который я использовал, чтобы получить все файлы с сетевого диска и вставить его в папку локального диска
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;
}
}
Полный код можно найти здесь. Буду очень признателен, если кто-то просмотрит код и предоставит какие-либо отзывы / решение этой проблемы.
3 ответа
Запуск службы под учетной записью локальной системы по умолчанию не будет иметь понятия общего ресурса. Они настроены под учетными записями пользователей.
Ваши 2 варианта
- Запустите службу под учетной записью пользователя, которой сопоставлены эти акции.
- Получите доступ к своей папке через ip-адрес вместо буквы диска. Однако вам нужно будет соответственно установить права доступа к файлу / папке.
Служба работает как локальная система (как ранее называлось). Если у вас сопоставлен сетевой диск с буквой локального диска, служба не сможет его использовать (поскольку сопоставленный сетевой диск всегда отображается только для пользовательского контекста, а не для всего компьютера / системы). Однако служба может получить доступ к общему ресурсу с помощью UNC \\server\share. Вы можете просмотреть путь UNC, если у вас есть подключенный сетевой диск, набрав "net use" в командной строке.
Если вы запускаете программу как пользователь, Windows автоматически аутентифицирует вас на удаленном общем ресурсе (если это еще не сделано путем добавления подключенного сетевого диска). Таким образом, Локальная система - это учетная запись компьютера, для которой необходимо установить права доступа целевого общего ресурса для имени компьютера, например workstation1$ (доступно только внутри домена, поскольку рабочая группа не знает другие компьютеры). Это должно быть сделано для прав доступа к файлам и общего ресурса, поскольку оба они независимы и могут ограничить вас от доступа.
В качестве альтернативы вы можете аутентифицироваться на удаленном сетевом ресурсе с помощью имени пользователя и пароля - в stackru есть отличная нить, которая показывает, как это можно сделать.
Естественно, вы также можете установить для службы имя пользователя / пароль в диспетчере служб (services.msc - дважды щелкните свой сервис и перейти на вкладку входа в систему), который имеет доступ к общему ресурсу. Таким образом, пользователю будет предоставлено разрешение "Войти как сервис", которое необходимо для этого.
Если сетевой файл используется совместно с учетной записью локальной системы, вам необходимо войти в систему как «Учетная запись локальной системы»,
Преимущество запуска ваших служб в качестве «учетной записи локальной системы» заключается в том, что служба имеет полный неограниченный доступ к локальным ресурсам.
Но есть и некоторые недостатки, поэтому будьте осторожны, чтобы не установить неавторизованные сервисы, так как сервис получает полный неограниченный доступ. Кроме того, если в сервисе есть ошибки, это может привести к проблемам с производительностью.