如何在安装期间为计划任务设置正确的用户
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 才能像这样工作。
此解决方案还假定两个项目输出位于同一文件夹中
我正在使用 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 才能像这样工作。
此解决方案还假定两个项目输出位于同一文件夹中