在服务中启动所需要的应用程序

来源:互联网 发布:网络小三毛图片 编辑:程序博客网 时间:2024/06/09 14:12

相关知识:

http://blog.csdn.net/findsafety/article/details/45971145

http://blog.csdn.net/findsafety/article/details/45971161



在上一篇文章http://blog.csdn.net/findsafety/article/details/45966883,我们添加了一个服务,在这个服务中可以启动一个exe,但是直接用那种方式的话是不能启动带有界面的程序的,原因见上面的相关知识


而我们要想实现在自启动的服务中开启我们的应用程序的话,那么就得按照相关知识中的第二篇文章那样做,具体如下

在上一篇文章所建立的service的基础上,

先在项目添加一个Interop.cs

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


namespace WindowsService1
{
    class Interop
    {
        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);






        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,
  path + app,
  String.Empty,
  ref sa, ref sa,
  false, 0, IntPtr.Zero,
  path, 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);


    }
}


然后再对原来的service里面的onstart进行修改


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using SafetyValve;


namespace WindowsService1
{
    public partial class Service1 : ServiceBase
    {
        string StartAppPath = @"C:\test\ECDDector\ECDDector\bin\Debug\ECDDector.exe";
        Process proc = new Process();  


        public Service1()
        {
            InitializeComponent();


          
        }


        protected override void OnStart(string[] args)
        {
            try
            {
        


                Interop.ShowMessageBox("This a message from AlertService.","AlertService Message");


                Interop.CreateProcess("cmd.exe", @"C:\Windows\System32\");


                //Interop.CreateProcess("ECDDector.exe", @"D:\vs2010\workspace\ECDDector\ECDDector\bin\Debug\");


             




                proc.StartInfo.FileName = StartAppPath; //注意路径
                proc.Start();
            }
            catch (System.Exception ex)
            {
               
            }   
        }


        protected override void OnStop()
        {
       
            proc.Kill();  //关闭进程
        }
    }
}



其他步骤如上一篇文章一样,这样就可以实现用服务来开机自启动程序了


代码下载:http://download.csdn.net/detail/findsafety/8737251


0 0
原创粉丝点击