运行 windows 服务时无法访问网络驱动器

Can't access the network drive while running the windows service

我正在尝试在 C# 中创建一个 windows 服务,该服务将从网络驱动器复制所有文件并将其粘贴到本地驱动器(假设在 C 驱动器中)。当我 运行 测试用例时,程序 运行s 成功但是当我安装 运行 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上找到。如果有人检查代码并提供任何 feedback/solution 解决此问题,我们将不胜感激。

运行在默认本地系统帐户下使用服务,将没有共享的概念。这些是在用户帐户下设置的。

你的 2 个选项

  1. 运行 您在 用户帐户 下的服务已映射这些共享
  2. 通过 IP 地址而不是驱动器号访问您的共享。但是,您需要相应地设置 file/folder 权限。

该服务 运行 作为本地系统(如前所述)。如果您有一个映射到本地驱动器盘符的网络驱动器,该服务将无法使用它(因为映射网络驱动器始终只映射到用户上下文,而不是整个 computer/system)。但是该服务可以通过 UNC \\server\share 访问共享。如果您只有一个映射的网络驱动器,您可以通过在命令提示符下键入 'net use' 查看 UNC 路径。

如果您 运行 您的程序作为用户 Windows 会自动在远程共享上对您进行身份验证(如果尚未通过添加映射的网络驱动器完成)。因此本地系统是您需要将目标共享的访问权限设置为计算机名称的计算机帐户,例如 workstation1$(仅在域内可用,因为工作组不知道其他计算机)。必须对文件权限和共享权限执行此操作,因为两者是独立的并且可以限制您的访问权限。

作为替代方案,您可以使用用户和密码在远程网络共享上进行身份验证 - 您可以在 Whosebug 中找到一个很好的线程here,它展示了如何实现这一点。

当然,您也可以在服务管理器中将服务设置为 user/password(services.msc - 双击您的服务并转到登录选项卡),他可以访问共享。通过这样做,用户将被授予为此所必需的 'login as service' 权限。

如果网络文件与本地系统帐户共享,则您需要以“本地系统帐户”身份登录,

运行您的服务作为“本地系统帐户”的优势在于该服务可以完全不受限制地访问本地资源。
但是也有一些缺点,所以要小心不要安装未经授权的服务,因为服务可以完全不受限制地访问。此外,如果服务有一些错误,可能会导致性能问题。