У меня есть Windows Сервис, который работает на системном уровне, и wi sh для запуска процесса (запуска апплета в системном трее) с повышенными привилегиями (эквивалентно запуску от имени администратора), но без необходимости явно указывать комбинация имени пользователя и пароля. Код может использовать существующую учетную запись системного уровня или учетные данные местоположения.
Идея состоит в том, что пользователь с правами администратора установит приложение, которое содержит приложение (WinForms), апплет в системном трее и службу Windows , Пользователь, который впоследствии входит в систему на этом компьютере, может иметь или не иметь права администратора. Апплет в системном трее должен работать тихо, не запрашивая у пользователя учетные данные или разрешения.
Поиск повернул код, чтобы использовать планировщик задач и создать одноразовое смещение задачи на 5 секунд:
// Get the path to the tray applet.
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
string dirService = Path.GetDirectoryName(path);
string pathTray = Path.Combine(dirService, ResqLib.GlobalConstants.FileName_Tray);
logEntry += $"{tabs}pathTray = \"{pathTray}\"{Environment.NewLine}";
// Start the system tray applet with administrative privilege.
using (var ts = new TaskService())
{
var t = ts.Execute(pathTray)
.Once()
.Starting(DateTime.Now.AddSeconds(5))
.AsTask(ResqLib.GlobalConstants.FileName_Tray);
}
Если бы я переопределил pathTray и использовал C:\Windows\System32\notepad.exe
, код работал бы без нареканий. Черт, код работает и из стандартного приложения WinForms. Проблема заключается в добавлении требования elevated privilege
(он же запускается от имени администратора).
Я ДЕЙСТВИТЕЛЬНО увидел код для использования до TaskDefinition
и указал учетные данные пользователя для пользователя с правами администратора.
Во что бы то ни стало, я наткнулся на этот кусок кода, но этот код не работает для приложения, требующего административного доступа (например, regedt32.exe
), но отлично работает для обычных исполняемых файлов, таких как notepad.exe
.
using (TaskService ts = new TaskService())
{
TaskDefinition newTask = ts.NewTask();
newTask.RegistrationInfo.Author = Environment.UserName;
newTask.RegistrationInfo.Description = ResqLib.GlobalConstants.FileName_Tray;
newTask.Principal.UserId = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Translate(typeof(NTAccount)).Value;
newTask.Principal.RunLevel = TaskRunLevel.Highest;
Trigger trigger = new DailyTrigger()
{
StartBoundary = DateTime.Now.AddSeconds(5),
Repetition = new RepetitionPattern(new TimeSpan(0, 1, 0), new TimeSpan(0, 1, 0), false),
Enabled = true,
};
newTask.Settings.MultipleInstances = TaskInstancesPolicy.IgnoreNew;
newTask.Settings.DisallowStartIfOnBatteries = true;
newTask.Settings.StopIfGoingOnBatteries = false;
newTask.Settings.AllowHardTerminate = false;
newTask.Settings.StartWhenAvailable = false;
newTask.Settings.RunOnlyIfNetworkAvailable = true;
newTask.Settings.IdleSettings.StopOnIdleEnd = false;
newTask.Settings.IdleSettings.RestartOnIdle = false;
newTask.Settings.Enabled = true;
newTask.Settings.Hidden = false;
newTask.Settings.RunOnlyIfIdle = false;
newTask.Settings.WakeToRun = false;
newTask.Settings.ExecutionTimeLimit = TimeSpan.FromSeconds(0);
newTask.Settings.Priority = System.Diagnostics.ProcessPriorityClass.Normal;
newTask.Triggers.Add(trigger);
newTask.Actions.Add(new ExecAction(pathTray));
ts.RootFolder.RegisterTaskDefinition(ResqLib.GlobalConstants.FileName_Tray, newTask);
}
Ответ не должен иметь ничего общего с планировщиком задач. Это может быть что угодно, даже новый процесс.
Я бы хотел оставить параметр, позволяющий службе взаимодействовать с выключенным рабочим столом. Запуск апплета в трее - единственное исключение, но в противном случае я не хочу, чтобы служба взаимодействовала с рабочим столом.
Мысли?
Сара