zoukankan      html  css  js  c++  java
  • 初学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

  • 相关阅读:
    springmvc log4j 配置
    intellij idea maven springmvc 环境搭建
    spring,property not found on type
    intellij idea maven 工程生成可执行的jar
    device eth0 does not seem to be present, delaying initialization
    macos ssh host配置及免密登陆
    centos7 搭建 docker 环境
    通过rest接口获取自增id (twitter snowflake算法)
    微信小程序开发体验
    gitbook 制作 beego 参考手册
  • 原文地址:https://www.cnblogs.com/qiaoke/p/6654449.html
Copyright © 2011-2022 走看看