我正在尝试在C#中创建一个Windows服务,它将复制网络驱动器中的所有文件并将其粘贴到本地驱动器中(假设在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;
}
}
完整的代码可以在gist here找到。如果有人查看代码并提供任何反馈/解决方案,我们将非常感激。
答案 0 :(得分:2)
在默认的本地系统帐户下运行服务,将没有共享的概念。这些是在用户帐户下设置的。
您的2个选项
答案 1 :(得分:1)
该服务确实以本地系统(如前所述)运行。如果您将映射的网络驱动器映射到本地驱动器号,则该服务无法使用它(因为映射的网络驱动器始终仅映射用户上下文,而不是整个计算机/系统)。但是,该服务可以通过UNC \\ server \ share访问共享。如果您只有一个映射的网络驱动器,则可以通过键入&net; net use&#39;来查看UNC路径。在命令提示符下。
如果您以用户身份运行程序,Windows会自动在远程共享中对您进行身份验证(如果尚未通过添加映射的网络驱动器来完成)。因此,本地系统是您将目标共享的访问权限设置为计算机名称所需的计算机帐户,例如workstation1 $(仅在域内可用,因为工作组不知道其他计算机)。必须为文件权限和共享权限执行此操作,因为两者都是独立的,可能会限制您访问。
作为替代方案,您可以使用用户和密码在远程网络共享中进行身份验证 - stackoverflow中有一个很好的线程,您可以找到here,它确实显示了如何实现此目的。
当然,您也可以在服务管理器中将服务设置为用户/密码(services.msc - 双击您的服务并转到登录选项卡),该用户/密码可以访问共享。通过这样做,用户将被授予“作为服务登录”的权限。对此必要的许可。