如何在安装期间为计划任务设置正确的用户

How to set correct User for scheduled Tasks during Installation

我正在使用 TaskScheduler 在部署期间设置计划任务。同时我使用设置文件来存储用户配置。现在,当任务计划程序运行时,它不会访问设置文件,因为用户不匹配。

在安装过程中,安装项目作为系统运行,以获得在应用程序目录中的写入权限。我是 运行 自定义操作,用于编写设置和计划任务,但用户不匹配。

如何确保用户匹配。我是否必须创建一个单独的应用程序来进行配置,以便设置可以在应用程序范围内?这对我来说毫无意义,因为这些设置在每个部署中都是不同的,并且是由用户而不是我设置的。

编辑: 用户设置文件的位置

string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ApplicationName");
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
Directory.SetCurrentDirectory(path);

创建计划任务的脚本片段

using Microsoft.Win32.TaskScheduler;

...

 if (Interval == null) Interval = TimeSpan.FromHours(1);
 if (Duration == null) Duration = TimeSpan.FromDays(1);

 using(TaskService ts = new TaskService())
 {
     var td = ts.NewTask();

     // attempt to get the correct user, gets system user as if ommitted
     td.Principal.UserId = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
     td.Principal.LogonType = TaskLogonType.InteractiveToken;

     td.Settings.ExecutionTimeLimit = TimeSpan.FromMinutes(5);
     var trigger = new DailyTrigger((short)DaysInterval)
     {
         StartBoundary = DateTime.Today,
         Repetition = new RepetitionPattern(Interval, Duration)
     };
     td.Triggers.Add(trigger);

     string exePath = System.Reflection.Assembly.GetEntryAssembly().Location;

     td.Actions.Add("\"" + exePath + "\"", "", Path.GetDirectoryName(exePath));
     ts.RootFolder.RegisterTaskDefinition("myTask", td);
 }

自定义操作,可以说太大了,在项目的不同文件上拆分,无法在此处共享

编辑:设置文件的设置字段示例

Properties.Settings _s = Properties.Settings.Default; 
_s.ClientIp = Tx_Ip.Text;
_s.ShopID = Tx_ShopId.Text;
_s.Save();

编辑: 我现在已经在安装期间和 运行 通过计划任务时记录了用户、UserPath 和 AppPath。

设置

User: NT-AUTORITÄT\SYSTEM 
UserPath: C:\Users\user\AppData\Local\appname 
AppPath: C:\Program Files (x86)\businessname\appname

计划任务

User: NT-AUTORITÄT\SYSTEM
UserPath: C:\Windows\system32\config\systemprofile\AppData\Local\appname
AppPath: C:\Program Files (x86)\businessname\appname

所以实际上是同一个User,只是UserPath不同。当我在安装过程中编写设置时,它们被保存在错误的位置,以后在计划任务期间无法访问。

此问题的解决方案是使用单独的项目来执行自定义操作,并且只使用应用程序范围进行设置。这样可以在安装期间创建配置。如果应用程序部署到设置默认文件夹,则只能使用管理员权限更改设置。

概念验证代码:

主要应用项目

using System;

namespace MyApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Properties.MyApplication.Default.Setting);
            Console.ReadLine();
        }
    }
}

自定义动作项目

using System;
using System.Configuration;
using System.IO;
using System.Reflection;

namespace WriteAppSettingsTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string exePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MyApplication.exe");
            Console.WriteLine(exePath);
            Console.ReadLine();

            Configuration cfg = ConfigurationManager.OpenExeConfiguration(exePath);
            ClientSettingsSection section = (ClientSettingsSection)cfg.GetSectionGroup("applicationSettings").Sections["MyApplication.Properties.MyApplication"];

            section.Settings.Get("Setting").Value.ValueXml.InnerText = "Edited Setting";
            section.SectionInformation.ForceSave = true;
            cfg.Save();
        }
    }
}

主应用程序需要一个设置文件。对于这个例子,我称之为“MyApplication.settings”。它需要一个名为“设置”的设置。在此示例中,我将值设置为“默认值”。

在设置项目中,在提交自定义操作下执行自定义操作项目。安装程序 class 属性 必须设置为 false 才能像这样工作。

此解决方案还假定两个项目输出位于同一文件夹中