【转】【C#】Windows服务运行exe程序

在“Windows服务”中,上述代码还是可以运行exe程序的,但是我们看不到。在“控制台应用程序”中,我们可以看到被执行的exe程序,但是到了“Windows服务”中,该exe变成了后台执行,无法与用户进行交互。
原因如下:
  默认情况下,服务是运行在session0下的,与普通的应用程序不在一个session,所以不能互动,但是我们可以利用函数“CreateProcessAsUser”来创建应用程序session下的进程,从而调用外部exe。
Windows服务(C#)显式运行外部exe程序源代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace SngjIPS_WindowsService
{class UserProcess{   #region Structures[StructLayout(LayoutKind.Sequential)]public struct SECURITY_ATTRIBUTES{public int Length;public IntPtr lpSecurityDescriptor;public bool bInheritHandle;}[StructLayout(LayoutKind.Sequential)]public struct STARTUPINFO{public int cb;public String lpReserved;public String lpDesktop;public String lpTitle;public uint dwX;public uint dwY;public uint dwXSize;public uint dwYSize;public uint dwXCountChars;public uint dwYCountChars;public uint dwFillAttribute;public uint dwFlags;public short wShowWindow;public short 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 uint dwProcessId;public uint dwThreadId;}#endregion#region Enumerationsenum TOKEN_TYPE : int{TokenPrimary = 1,TokenImpersonation = 2}enum SECURITY_IMPERSONATION_LEVEL : int{SecurityAnonymous = 0,SecurityIdentification = 1,SecurityImpersonation = 2,SecurityDelegation = 3,}enum WTSInfoClass{InitialProgram,ApplicationName,WorkingDirectory,OEMId,SessionId,UserName,WinStationName,DomainName,ConnectState,ClientBuildNumber,ClientName,ClientDirectory,ClientProductId,ClientHardwareId,ClientAddress,ClientDisplay,ClientProtocolType}#endregion#region Constantspublic const int TOKEN_DUPLICATE = 0x0002;public const uint MAXIMUM_ALLOWED = 0x2000000;public const int CREATE_NEW_CONSOLE = 0x00000010;public const int IDLE_PRIORITY_CLASS = 0x40;public const int NORMAL_PRIORITY_CLASS = 0x20;public const int HIGH_PRIORITY_CLASS = 0x80;public const int REALTIME_PRIORITY_CLASS = 0x100;#endregion#region Win32 API Imports[DllImport("kernel32.dll", SetLastError = true)]private static extern bool CloseHandle(IntPtr hSnapshot);[DllImport("kernel32.dll")]static extern uint WTSGetActiveConsoleSessionId();[DllImport("wtsapi32.dll", CharSet = CharSet.Unicode, SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]static extern bool WTSQuerySessionInformation(System.IntPtr hServer, int sessionId, WTSInfoClass wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned);[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]public extern static bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment,String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);[DllImport("kernel32.dll")]static extern bool ProcessIdToSessionId(uint dwProcessId, ref uint pSessionId);[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess,ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType,int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);[DllImport("kernel32.dll")]static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);[DllImport("advapi32", SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle);#endregionpublic static string GetCurrentActiveUser(){IntPtr hServer = IntPtr.Zero, state = IntPtr.Zero;uint bCount = 0;// obtain the currently active session id; every logged on user in the system has a unique session id  uint dwSessionId = WTSGetActiveConsoleSessionId();string domain = string.Empty, userName = string.Empty;if (WTSQuerySessionInformation(hServer, (int)dwSessionId, WTSInfoClass.DomainName, out state, out bCount)){domain = Marshal.PtrToStringAuto(state);}if (WTSQuerySessionInformation(hServer, (int)dwSessionId, WTSInfoClass.UserName, out state, out bCount)){userName = Marshal.PtrToStringAuto(state);}return string.Format("{0}\\{1}", domain, userName);}/// <summary>  /// Launches the given application with full admin rights, and in addition bypasses the Vista UAC prompt  /// </summary>  /// <param name="applicationName">The name of the application to launch</param>  /// <param name="procInfo">Process information regarding the launched application that gets returned to the caller</param>  /// <returns></returns>  public static bool StartProcessAndBypassUAC(String applicationName, String command, out PROCESS_INFORMATION procInfo){uint winlogonPid = 0;IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero;procInfo = new PROCESS_INFORMATION();// obtain the currently active session id; every logged on user in the system has a unique session id  uint dwSessionId = WTSGetActiveConsoleSessionId();// obtain the process id of the winlogon process that is running within the currently active session  Process[] processes = Process.GetProcessesByName("winlogon");foreach (Process p in processes){if ((uint)p.SessionId == dwSessionId){winlogonPid = (uint)p.Id;}}// obtain a handle to the winlogon process  hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);// obtain a handle to the access token of the winlogon process  if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken)){CloseHandle(hProcess);return false;}// Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser  // I would prefer to not have to use a security attribute variable and to just   // simply pass null and inherit (by default) the security attributes  // of the existing token. However, in C# structures are value types and therefore  // cannot be assigned the null value.  SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();sa.Length = Marshal.SizeOf(sa);// copy the access token of the winlogon process; the newly created token will be a primary token  if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup)){CloseHandle(hProcess);CloseHandle(hPToken);return false;}// By default CreateProcessAsUser creates a process on a non-interactive window station, meaning  // the window station has a desktop that is invisible and the process is incapable of receiving  // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user   // interaction with the new process.  STARTUPINFO si = new STARTUPINFO();si.cb = (int)Marshal.SizeOf(si);si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop  // flags that specify the priority and creation method of the process  int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;// create a new process in the current user's logon session  bool result = CreateProcessAsUser(hUserTokenDup,        // client's access token  applicationName,        // file to execute  command,                // command line  ref sa,                 // pointer to process SECURITY_ATTRIBUTES  ref sa,                 // pointer to thread SECURITY_ATTRIBUTES  false,                  // handles are not inheritable  dwCreationFlags,        // creation flags  IntPtr.Zero,            // pointer to new environment block   null,                   // name of current directory   ref si,                 // pointer to STARTUPINFO structure  out procInfo            // receives information about new process  );// invalidate the handles  CloseHandle(hProcess);CloseHandle(hPToken);CloseHandle(hUserTokenDup);return result; // return the result  }}}

调用如下:

UserProcess.PROCESS_INFORMATION pInfo = new UserProcess.PROCESS_INFORMATION();
UserProcess.StartProcessAndBypassUAC("xxx.exe", string.Empty, out pInfo);

注意,该程序一定要写在“Windows服务”程序的代码中才有效,如果你把本程序代码写在“控制台应用程序”中运行是没有任何效果的。

原文地址:https://cognize.me/windowsservice/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59536.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webSocket的使用文档

webSocket的使用文档 1.webSocket介绍2.webSocket使用 1.webSocket介绍 WebSocket是在单个TCP连接上提供全双工通信的协议。它允许双方同时进行数据传输&#xff0c;而不需要等待对方的响应&#xff0c;简单说就是他是服务器和客户端相互主动传输信息的约定协议。 优点&#xf…

C++(Qt)软件调试---符号转换工具cv2pdb (24)

C(Qt)软件调试—符号转换工具cv2pdb &#xff08;24&#xff09; 文章目录 C(Qt)软件调试---符号转换工具cv2pdb &#xff08;24&#xff09;[toc]1、概述&#x1f41c;2、下载cv2pdb&#x1fab2;3、qt程序使用cv2pdb&#x1f9a7;1.1 方法1&#xff1a;命令行1.2 方法2&#…

基于Java Springboot宠物流浪救助系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA 数据库&#xff1a;MySQL…

实战OpenCV之目标检测

基础入门 目标检测是计算机视觉中的一个重要任务,它旨在识别图像或视频帧中的多个对象,并对每个对象进行定位和分类。目标检测任务通常包括以下几个主要步骤。 输入图像:接收一张或多张图像作为输入。 特征提取:从输入图像中提取有用的特征。 候选区域生成:生成一组可能包…

如何在手机上完整下载B站视频并保存到相册?

作为国内最受欢迎的视频平台之一&#xff0c;B站(哔哩哔哩)不仅有丰富的创作者内容&#xff0c;还吸引了大量年轻用户。对于热爱动画、影视剪辑、Vlog等各类视频的观众来说&#xff0c;有时希望能将这些视频下载到手机相册中&#xff0c;方便随时观看或分享。如何在不损失画质的…

uniapp隐藏自带的tabBar

uniapp隐藏自带的tabBar 场景: 微信小程序在使用自定义tabBar组件时, 隐藏uniapp自带的tabBar <template> <!-- index页面 --> </template> <script setup> import { onShow } from /utils/wxUtils onShow(() > {uni.hideTabBar() // 隐藏自带的tab…

My_SQL day3

知识点&#xff1a;约束 1.dafault 默认约束 2.not null 非空约束 3.unique key 唯一约束 4.primary key 主键约束 5.anto_increment 自增长约束 6.foreign key 外键约束 知识点&#xff1a;表关系 1.一对一 2.一对多 3.多对多 知识点&#xff1a;约束 1.default 默认约束 …

C++基础:Pimpl设计模式的实现

2024/11/14: 在实现C17的Any类时偶然接触到了嵌套类的实现方法以及Pimpl设计模式&#xff0c;遂记录。 PIMPL &#xff08; Private Implementation 或 Pointer to Implementation &#xff09;是通过一个私有的成员指针&#xff0c;将指针所指向的类的内部实现数据进行隐藏。 …

从JVM的角度,来分析为什么Java中是值传递?

从 JVM 的角度来看&#xff0c;Java 中的参数传递之所以是值传递&#xff0c;是因为在 JVM 执行方法调用时&#xff0c;参数的值&#xff08;不论是基本类型还是引用类型&#xff09;都被复制并压入调用栈的帧&#xff08;stack frame&#xff09;中。让我们从 JVM 的内存模型和…

Navicat 17 功能简介 | 单元格编辑器

Navicat 17 功能简介 | 单元格编辑器 本期&#xff0c;我们一起了解 Navicat 17 出色的数据操作功能的单元格编辑器。单元格编辑器支持文本、十六进制、图像和网页四种格式的数据编辑&#xff0c;位于底部的编辑器窗格&#xff0c;为你编辑更大容量的数据信息提供足够的显示和操…

Unity自动LOD工具AutoLOD Mesh Decimator的使用

最近在研究大批量物体生成&#xff0c;由于我们没有专业美术&#xff0c;在模型减面工作上没有人手&#xff0c;所以准备用插件来实现LOD功能&#xff0c;所以找到了AutoLOD Mesh Decimator这个插件。 1&#xff0c;导入插件后&#xff0c;我们拿个实验的僵尸狗来做实验。 空…

爬虫补环境案例---问财网(rpc,jsdom,代理,selenium)

目录 一.环境检测 1. 什么是环境检测 2.案例讲解 二 .吐环境脚本 1. 简介 2. 基础使用方法 3.数据返回 4. 完整代理使用 5. 代理封装 6. 封装所有使用方法 jsdom补环境 1. 环境安装 2. 基本使用 3. 添加参数形式 Selenium补环境 1. 简介 2.实战案例 1. 逆向目…

免费,WPS Office教育考试专用版

WPS Office教育考试专用版&#xff0c;不仅满足了考试需求&#xff0c;更为教育信息化注入新动力。 https://pan.quark.cn/s/609ef85ae6d4

Vue前端开发,组件及组件的使用

什么是组件 组件(Component)是Vue中最强大的功能之一&#xff0c;每个Vue 文件就是一个个独立的组件&#xff0c;组件也可以被其他组件调用&#xff0c;形成嵌套关系&#xff0c;大部分的应用都是由各类不同功能的小组件进行构建&#xff0c;形成一个功能强大的大组件树系统&a…

Docker 中启动 NGINX 并配置 HTTPS 443 端口

在 Docker 中启动 NGINX 并配置 HTTPS 443 端口时&#xff0c;你需要挂载 SSL 证书和密钥文件&#xff0c;并更新 NGINX 配置文件。以下是详细步骤&#xff1a; 1. 准备证书文件 确保你有 SSL 证书和私钥文件&#xff0c;通常是两个文件&#xff1a; certificate.crt&#x…

政务数据治理专栏开搞!

写在前面 忙忙碌碌干了一年政务数据治理的工作&#xff0c;从法人数据到自然人&#xff0c;从交通到地理信息等等&#xff0c;突发想法开一个专栏讲一讲政务数据遇到的问题&#xff0c;以及治理的成效&#xff0c;或许有朋友爱看。 政务数据&#xff0c;又称之为政务数据资源&a…

前端在PC端实现支付思路流程

一.去支付 1.前端点击“去支付”按钮&#xff0c;请求订单详情接口&#xff0c;传递订单的id、订单号给后端和请求支付方式接口 2.后端返回支付信息和支付方式数据 二.弹出支付窗口 接收支付信息和支付方式数据后&#xff0c;前端弹出支付弹窗 三.确认支付 前端无论选择任何…

The 3rd Universal CupStage 15: Chengdu, November 2-3, 2024(2024ICPC 成都)

Problem L. Recover Statistics 题目意思&#xff1a; 给定a, b, c三个值&#xff0c;确保构造的数列中包含满足题目的数量 解题思路&#xff1a; 100 中 选择a 50个&#xff0c; b45个&#xff0c; c4个。 #include <iostream>using namespace std;using ll long …

VUE3实现好看的世界建筑中国建筑网站源码

文章目录 1.设计来源1.1 网站主界面1.2 登录界面1.3 注册界面1.4 特色建筑展览界面1.5 世界建筑介绍界面1.6 世界建筑介绍 - 详情界面1.7 中国建筑介绍界面1.8 中国建筑介绍 - 详情界面1.9 关于我们界面 2.效果和源码2.1 动态效果2.2 源代码2.3 目录结构 源码下载万套模板&…

「人眼视觉不再是视频消费的唯一形式」丨智能编解码和 AI 视频生成专场回顾@RTE2024

你是否想过&#xff0c;未来你看到的电影预告片、广告&#xff0c;甚至新闻报道&#xff0c;都可能完全由 AI 生成&#xff1f; 在人工智能迅猛发展的今天&#xff0c;视频技术正经历着一场前所未有的变革。从智能编解码到虚拟数字人&#xff0c;再到 AI 驱动的视频生成&#…