• 初学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:WindowsSystem32"); //执行
    这里的exe可以是任意的。
    2、在服务里建了个线程,延时执行exe文件,避免了第2个问题,同时循环执行,很多软件的服务不断弹出新闻广告就这这样子。
    3、管理员权限问题:
    在项目上点右键选“属性”,选择“安全性”,勾选复选框“启用ClickOnce”

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

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

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

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

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

  • 相关阅读:
    2013腾讯编程马拉松初赛第〇场(3月20日)湫湫系列故事——植树节 HDOJ 4503
    组合模式(Composite)
    Git Push 避免用户名和密码方法
    [Yii2] 快速套模板,加载JS,CSS(HTML标签<base>)
    phpstorm 2016.2.x 最新版激活方法
    PHP实现四种基本排序算法
    linux下查看负载均衡的两种方法
    Redis各类型应用场景
    HTTP协议2:请求、响应、缓存 2017-03-16 11:20 197人阅读 评论(0) 收藏
    HTTP协议1:工作原理 2017-03-16 11:18 39人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/qiaoke/p/6654449.html
Copyright © 2020-2023  润新知