Windows服务启动exe无界面终极解决方案

目录

1、前言

2、网上方案

3、我的方案

3.1、简单不粗暴

3.2、优美

4、实现过程

5、源代码地址

6、附件和工具的地址


1、前言

        我这个方案(C#操作)是彻底解决【从Windows服务启动程序exe,程序无界面】问题的终极解决方案,终极方案,绝对的终极方案,本来打算收钱的,还是算了,你们也不容易(呵呵,有些人一点东西就要你VIP,还没个锤子用,呵呵呵呵,我免费,关注我一下就行。后附代码下载地址。

        由于安全性问题,Vista以后的Windows都会出现该问题,从服务中调用/启动其他程序出现无界面,但是任务管理器中可以看到已经成功启动,就是无操作界面,具体出现该状况的原因大家自行搜索。

        我的方法绝对可行。

PS:服务是自己写的,需要实现其他特殊功能,其他手法绕过自建服务使用封装方式反而复杂了。简而言之,本文的应用场景是:服务必须自建,还要打开外部exe。

2、网上方案

        网上有各种各样的方案,绝大部分都有一样的,都是是调用系统API,如CreateProcess之类的,然并卵,并不能彻底解决。

3、我的方案

        我的方案极其简单而不粗暴,反而优美。

3.1、简单不粗暴

        我的方案是使用计划任务功能启动指定程序。任务计划的启动不受服务限制,和服务的边界不太一样。不需要特别多的代码就可以实现,其实就是实现添加任务计划,简单吧。网上的普遍的方法(调用系统API的方式),光结构和调试就够你们喝一壶了,还得通过其他API调用和设置其他信息,比如创建和复制现有执行令牌(DuplicateTokenEx方法),要实现这功能,粗暴得狠。

        而我这个不用,啥都不用。

3.2、优美

        创建任务寥寥十几行代码,优美得狠。

4、实现过程

        实现过程即任务计划实现过程,C#有3种方法,其实就是2种,一种是使用API创建任务,这个方法其实可以通过系统调用现有dll库实现,最后一种是使用开源库。建议用开源库方式。

        调用系统的dll,这dll就是C:\Windows\System32\taskschd.dll,在C#里直接引用就行,它实现创建任务API的C#封装,很简单。使用TaskSchedulerClass类连接、创建修改任务计划,很简单,我这不是主推方法,不贴代码,但源码地址里有。

        使用开源库TaskScheduler,可以实现,命名空间为Microsoft.Win32.TaskScheduler,下载地址为:https://github.com/dahall/TaskScheduler。例子为Examples · dahall/TaskScheduler Wiki · GitHub

    public static void AddOrRunWinTask( string sTaskName, string sExePath, string sArgs = null )
    {
        var task = TaskService.Instance.FindTask(sTaskName, true);

        if ( task != null )
        {
            task.Definition.Triggers[0].StartBoundary = DateTime.Now.AddSeconds ( 10 );
            task.RegisterChanges ();
        }
        else
        {
            var td = TaskService.Instance.NewTask ();

            td.RegistrationInfo.Author = "白羊佐CSDN";
            td.RegistrationInfo.Description = "用于跨域启动特定程序";

            td.Settings.ExecutionTimeLimit = TimeSpan.Zero;//
            td.Settings.DisallowStartIfOnBatteries = false;
            td.Settings.RunOnlyIfIdle = false;
            td.Settings.RunOnlyIfNetworkAvailable = false;
            //此处注意,如果你待启动程序需要管理员权限运行,必须使用Highest,否则使用LUA就行
            td.Principal.RunLevel = TaskRunLevel.Highest;
            //获取Administrators的GroupID
            string sGpId = GetGroupID();
            //此处最为关键,如果不指定用户名ID或组名ID,依旧不显示界面,因为创建时的用户为SYSTEM
            td.Principal.GroupId = sGpId;

            var trigger = (TimeTrigger)td.Triggers.Add( new TimeTrigger() );
            trigger.StartBoundary = DateTime.Now.AddSeconds ( 10 );
            trigger.ExecutionTimeLimit = TimeSpan.Zero;
            trigger.Enabled = true;
            td.Actions.Add ( new ExecAction ( sExePath, sArgs ) );

            task = TaskService.Instance.RootFolder.RegisterTaskDefinition ( sTaskName, td );
        }

        //打开表示立即运行
        //var rz = task.Run ();
    }

       注意,注意,再注意:两个细节放在了博客园了,运行遇到问题过去看。此处没更新。后面代码也没更新

    private static string GetGroupID ()
    {
        string sGid = null;
        
        System.DirectoryServices.AccountManagement.PrincipalContext pc = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Machine);
        var identity = System.DirectoryServices.AccountManagement.GroupPrincipal.FindByIdentity(pc, "Administrators");
        
        if ( identity != null )
        {
            sGid = identity.Sid.Value;
        }

        return sGid;
    }

完工,收工,以上代码完全可以实现,没必要现在我的源代码了。省下载钱。

5、源代码地址

https://download.csdn.net/download/fisher_china/87966293

6、附件和工具的地址

https://download.csdn.net/download/fisher_china/87966356

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值