初学c# -- c#创建开机自启服调用外部交互式exe文件

在c#创建的开机自启动服务里,调用外部可执行文件有以下问题:
1、带窗口的交互式的exe文件调用后,实际并没有被执行;
2、服务是随windows启动的,服务启动后可能windows桌面还没出来,会报错误,导致程序无法执行;
3、安装服务需管理员权限
等问题。
对上面的一些问题进行处理:
1、调用带窗口的交互式的exe文件,主要是Interop.cs文件,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleWithWindowsService
{
    class Interop
    {
        public static void CreateProcess(string app, string path)
        {
            bool result;
            IntPtr hToken = WindowsIdentity.GetCurrent().Token;
            IntPtr hDupedToken = IntPtr.Zero;

            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
            sa.Length = Marshal.SizeOf(sa);

            STARTUPINFO si = new STARTUPINFO();
            si.cb = Marshal.SizeOf(si);

            int dwSessionID = WTSGetActiveConsoleSessionId();
            result = WTSQueryUserToken(dwSessionID, out hToken);

            if (!result)
            {
                ShowMessageBox("WTSQueryUserToken failed", "AlertService Message");
            }

            result = DuplicateTokenEx(
                  hToken,
                  GENERIC_ALL_ACCESS,
                  ref sa,
                  (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
                  (int)TOKEN_TYPE.TokenPrimary,
                  ref hDupedToken
               );

            if (!result)
            {
                ShowMessageBox("DuplicateTokenEx failed", "AlertService Message");
            }

            IntPtr lpEnvironment = IntPtr.Zero;
            result = CreateEnvironmentBlock(out lpEnvironment, hDupedToken, false);

            if (!result)
            {
                ShowMessageBox("CreateEnvironmentBlock failed", "AlertService Message");
            }

            result = CreateProcessAsUser(
                                 hDupedToken,
                                 app,
                                 String.Empty,
                                 ref sa, ref sa,
                                 false, 0, IntPtr.Zero,
                                 null, ref si, ref pi);

            if (!result)
            {
                int error = Marshal.GetLastWin32Error();
                string message = String.Format("CreateProcessAsUser Error: {0}", error);
                ShowMessageBox(message, "AlertService Message");
            }

            if (pi.hProcess != IntPtr.Zero)
                CloseHandle(pi.hProcess);
            if (pi.hThread != IntPtr.Zero)
                CloseHandle(pi.hThread);
            if (hDupedToken != IntPtr.Zero)
                CloseHandle(hDupedToken);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public Int32 dwProcessID;
            public Int32 dwThreadID;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public Int32 Length;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }

        public enum SECURITY_IMPERSONATION_LEVEL
        {
            SecurityAnonymous,
            SecurityIdentification,
            SecurityImpersonation,
            SecurityDelegation
        }

        public enum TOKEN_TYPE
        {
            TokenPrimary = 1,
            TokenImpersonation
        }

        public const int GENERIC_ALL_ACCESS = 0x10000000;

        [DllImport("kernel32.dll", SetLastError = true,
            CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool CloseHandle(IntPtr handle);

        [DllImport("advapi32.dll", SetLastError = true,
            CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern bool CreateProcessAsUser(
            IntPtr hToken,
            string lpApplicationName,
            string lpCommandLine,
            ref SECURITY_ATTRIBUTES lpProcessAttributes,
            ref SECURITY_ATTRIBUTES lpThreadAttributes,
            bool bInheritHandle,
            Int32 dwCreationFlags,
            IntPtr lpEnvrionment,
            string lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            ref PROCESS_INFORMATION lpProcessInformation);

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool DuplicateTokenEx(
            IntPtr hExistingToken,
            Int32 dwDesiredAccess,
            ref SECURITY_ATTRIBUTES lpThreadAttributes,
            Int32 ImpersonationLevel,
            Int32 dwTokenType,
            ref IntPtr phNewToken);

        [DllImport("wtsapi32.dll", SetLastError = true)]
        public static extern bool WTSQueryUserToken(
            Int32 sessionId,
            out IntPtr Token);

        [DllImport("userenv.dll", SetLastError = true)]
        static extern bool CreateEnvironmentBlock(
            out IntPtr lpEnvironment,
            IntPtr hToken,
            bool bInherit);

        public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
        public static void ShowMessageBox(string message, string title)
        {
            int resp = 0;
            WTSSendMessage(
                WTS_CURRENT_SERVER_HANDLE,
                WTSGetActiveConsoleSessionId(),
                title, title.Length,
                message, message.Length,
                0, 0, out resp, false);
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int WTSGetActiveConsoleSessionId();

        [DllImport("wtsapi32.dll", SetLastError = true)]
        public static extern bool WTSSendMessage(
            IntPtr hServer,
            int SessionId,
            String pTitle,
            int TitleLength,
            String pMessage,
            int MessageLength,
            int Style,
            int Timeout,
            out int pResponse,
            bool bWait);
    }
}

在服务调用问文件WindowsService.cs里面这样引用
Interop.CreateProcess(@"d:\getp.exe", @"C:\Windows\System32\"); //执行
这里的exe可以是任意的。
2、在服务里建了个线程,延时执行exe文件,避免了第2个问题,同时循环执行,很多软件的服务不断弹出新闻广告就这这样子。
3、管理员权限问题:
在项目上点右键选“属性”,选择“安全性”,勾选复选框“启用ClickOnce”

最后返回“安全性”,将复选框“启用ClickOnce”去掉。

这样就可以管理员权限安装了。

本例安装进程名为“我的数据服务”,每隔200秒执行getp.exe文件。
运行时可选择“1”进行安装,“3”进行卸载,安装完毕后在服务里可以看到“我的数据服务”项目。

比写注册表添加开机启动好多了,就算放个木马也不会报病毒了

下载:http://pan.baidu.com/s/1pLRnm8j

时间: 2024-12-20 10:04:11

初学c# -- c#创建开机自启服调用外部交互式exe文件的相关文章

CentOS7_86_64创建Oracle实例且设置开机自启以及允许远程连接

一.前言 先说明下,这里系统是CentOS7_86_64,Oracle版本是Oracle10g R2,假设系统和数据库都已安装完毕.前面有一篇文章详细说明了CentOS7下安装Oracle10g的流程,需要的同学可以去看一下.传送门:CentOS7_86_64安装Oracle10g R2血泪史. 二.检查/设置系统防火墙 说明:这里主要是为了设置oracle允许远程连接,如果没有这个需求,可以先不用管. 1.客户端检测网络通过性 此步骤不执行也可以,如果没条件检测的话.这里只是说明下网络是否正常

Windows7 开机自启脚本

背景 如何开机自启 快捷方式 第一步 第二步 第三步 第四步 VB实现 逻辑脚本 VB代码 实现效果 两种方法区别 总结 背景 有些时候,我们需要做一些定时,或者指定时间运行的任务.然而相对于普通电脑和服务器而言,还是有一定的区别的. 对于服务器而言,基本上会一直处于一个运行状态.所以想要在指定的时间运行程序,或者脚本也会是很方面的.大不了写个死循环一直监听呗,虽然消耗了点服务器资源,但这点消耗不会很大,也是可以接受的.如果觉得自己写的不够精简,高效. 还可以使用Celery, Aspsched

cenOS系统,chkconfig设置程序开机自启--mysql、tomcat、redis、fastdfs--nginx/fdfs_trackerd/fdfs_storaged

设置程序开机启动就是将程序的启动脚本添加到/etc/init.d目录下,或者将启动路径写入/etc/rc.d/rc.local文件里面. 设置mysql开机启动 cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql chkconfig --add mysql chkconfig mysql on 设置fdfs_tracker开机启动 cp /usr/local/src/FastDFS/init.d/fdfs_tracke

centOS学习part7:Oracle开机自启配置

0 上一章(http://www.cnblogs.com/souvenir/p/3884904.html)我们用了很多时间以及很长的篇幅来介绍oracle的整个安装过程,希望对大家用所帮助.oracle在完毕后自动启动了数据库服务,但是没有设置开机自启.本章我们将来了解下如何配置oracle的开机自启. 1 修改dbstart及dbshut 用oracle用户登录系统,然后分别修改产品目录下的两个oracle脚本文件 修改的主要内容就是将ORACLE_HOME_LISTNER设置为$ORACLE

Linux下设置Nginx开机自启

1.本地环境 [[email protected] ~]#cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) 2.在/etc/init.d创建nginx文件,并添加如下内容 [[email protected] ~]# vim /etc/init.d/nginx 脚本内容如下: #!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chk

Ubuntu 1604 安装配置 kafka,并配置开机自启(systemctl)

安装 kafka 需要先安装 jdk.一.下载官网:http://kafka.apache.org/downloads.html 二.安装 安装参考:https://segmentfault.com/a/1190000012990954 1. 解压安装(我的安装目录/opt/kafka/) # tar -zvxf kafka_2.11-2.1.0.tgz 2.  修改配置 # vim /opt/kafka/kafka_2.11-2.1.0/config/server.properties 3.

编译安装nginx时配置开机自启

详细编译安装nginx请参考[Nginx目录结构与配置文件详解]以及[Nginx安装部署],在这里就进行简单安装 安装Nginx 环境介绍 操作系统: [[email protected] ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [[email protected] ~]# uname -a Linux localhost.localdomain 3.10.0-957.el7.x86_64 #1 SMP T

mac下设置redis开机自启

未设置开机自启时,每次都会执行命令如下: redis-server /usr/local/redis-5.0.5/redis.conf 下面开始设置redis开机自启 你需要.plist文件来指定需要开机启动的程序.首先来创建一个.plist文件: sudo vim /Library/LaunchDaemons/io.redis.redis-server.plist 以下是开机启动的.plist配置文件的示例: <?xml version="1.0" encoding="

windows下面使用nssm设置新的服务实现开机自启等

1.下载: http://nssm.cc/download/?page=download 2.解压: 根据自己的系统选择相应的32bit或者64bit,然后将相应的可执行文件拷贝到系统环境中.配置环境变量: 3.配置: cmd命令行模式下,进入到nssm的目录或者直接运行下面的命令: nssm install NodeJS (NodeJS为测试环境下面的安装的服务名称,该测试案例是node程序) 在Path 中选择你安装的node.exe,Startup directory 选择你的node应用