C#安装需要管理权限的软件

时间:2016-06-20 23:16:01

标签: c# installer startup uac elevated-privileges

我开发了一个小型C#软件,它与一台始终连接到电脑的硬件连接。由于该软件需要管理权限,并且我希望它在PC启动时启动,我正在评估部署它的最佳方式。

理想情况是创建一个安装程序,负责在安装过程中禁用该特定软件的UAC提示,这样每次特定软件启动时我都不会收到任何UAC提示。这可能吗?有哪些可能的选择?

2 个答案:

答案 0 :(得分:0)

您无法创建安装应用程序的设置,以便交互式应用程序需要管理员权限但不提示。安装与应用程序分开。

假设您构建了基于MSI的Windows Installer设置:

安装几乎肯定需要管理员权限才能安装,而用于构建MSI的工具会让你这么说,安装会提示提升。

构建运行提升的应用程序的方式是拥有一个在启动时请求提升的清单。

如果您真的希望您的代码在机器启动时运行,那么它必须作为服务安装。实际上所有其他方法(Run注册表项,Program菜单中的Startup文件夹等)都会在用户登录时调用(非系统启动时)。如果您需要UI来对设备执行某些操作,那么您将需要一个与该服务对话的Windows UI应用程序(因为服务无法与桌面交互)。

答案 1 :(得分:0)

我找到了在启动时运行具有管理员权限的应用程序的答案。

基本上我刚创建了一个运行级别最高的任务,并且您的触发器在登录时。

我在此存储库中的 vb 中找到了代码:https://bitbucket.org/trparky/start_program_at_startup_without_uac

Sub addTask(taskName As String, taskDescription As String, taskEXEPath As String, taskParameters As String)
        taskName = taskName.Trim
        taskDescription = taskDescription.Trim
        taskEXEPath = taskEXEPath.Trim
        taskParameters = taskParameters.Trim

        If Not IO.File.Exists(taskEXEPath) Then
            MsgBox("Executable path not found.", MsgBoxStyle.Critical, Me.Text)
            Exit Sub
        End If

        Dim taskService As TaskService = New TaskService()
        Dim newTask As TaskDefinition = taskService.NewTask

        newTask.RegistrationInfo.Description = taskDescription

        If chkEnabled.Checked Then newTask.Triggers.Add(New LogonTrigger)

        Dim exeFileInfo As New FileInfo(taskEXEPath)

        newTask.Actions.Add(New ExecAction(Chr(34) & taskEXEPath & Chr(34), taskParameters, exeFileInfo.DirectoryName))

        newTask.Principal.RunLevel = TaskRunLevel.Highest
        newTask.Settings.Compatibility = TaskCompatibility.V2_1
        newTask.Settings.AllowDemandStart = True
        newTask.Settings.DisallowStartIfOnBatteries = False
        newTask.Settings.RunOnlyIfIdle = False
        newTask.Settings.StopIfGoingOnBatteries = False
        newTask.Settings.AllowHardTerminate = False
        newTask.Settings.UseUnifiedSchedulingEngine = True
        newTask.Settings.ExecutionTimeLimit = Nothing
        newTask.Settings.Priority = ProcessPriorityClass.Normal
        newTask.Principal.LogonType = TaskLogonType.InteractiveToken

        taskService.RootFolder.SubFolders(strTaskFolderName).RegisterTaskDefinition(taskName, newTask)

        newTask.Dispose()
        taskService.Dispose()
        newTask = Nothing
        taskService = Nothing
    End Sub

所以我所做的就是将这段代码翻译成c#并进行测试

using Microsoft.Win32.TaskScheduler;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CreateTaskTest
{
    class Program
    {
        static void Main(string[] args)
        {
            addTask();
            //deleteTask();
        }

        static void addTask()
        {
            // Get the service on the local machine
            using (TaskService ts = new TaskService())
            {
                // Create a new task definition and assign properties
                TaskDefinition newTask = ts.NewTask();
                newTask.RegistrationInfo.Description = "Rondinelli Morais Create Task";

                newTask.Triggers.Add(new LogonTrigger());

                newTask.Actions.Add(new ExecAction("C:\\Windows\\regedit.exe"));

                newTask.Principal.RunLevel = TaskRunLevel.Highest;
                newTask.Principal.LogonType = TaskLogonType.InteractiveToken;

                newTask.Settings.Compatibility = TaskCompatibility.V2_1;
                newTask.Settings.AllowDemandStart = true;
                newTask.Settings.DisallowStartIfOnBatteries = false;
                newTask.Settings.RunOnlyIfIdle = false;
                newTask.Settings.StopIfGoingOnBatteries = false;
                newTask.Settings.AllowHardTerminate = false;
                newTask.Settings.UseUnifiedSchedulingEngine = true;
                newTask.Settings.Priority = System.Diagnostics.ProcessPriorityClass.Normal;

                // Register the task in the root folder
                ts.RootFolder.RegisterTaskDefinition(@"Test", newTask);

                newTask.Dispose();
                ts.Dispose();
            }
        }

        static void deleteTask()
        {
            using (TaskService ts = new TaskService())
            {

                var tasks = ts.FindAllTasks(new System.Text.RegularExpressions.Regex(@"Test"));

                foreach(var task in tasks){
                    ts.RootFolder.DeleteTask(task.Name);
                }
            }
        }
    }
}

我在示例中使用 regedit.exe ,因为此程序需要管理员权限才能运行。

创建任务,进行注销并再次登录,登录后您将看到注册表。

OBS:要创建或删除任务,您已经以管理员身份运行visual studio,或将此代码放入程序的安装过程中

让我知道这是否适用于某人

相关问题