这篇文章主要讲Service如何进行用户交互,我们知道,service是没有UI的,它运行在SYSTEM用户,权限很高,在它里面直接执行程序(如ShellExecute,CreateProcess等)将会失败,但有时我们的确需要在Service里面做这些事情(事实上,我觉得这种不太合理,应该通过其他方式来进行规避),我们应该怎么做呢?下面说一下我在RASU项目中的解决方案。
其实最本质上是用CreateProcessAsUser这个API,它与CreateProcess不同之处在于,它需要传一个用户的token的HANDLE,这个句柄就代表一个用户。
这就会带来一个问题,如果得到当前激活用户的token?
用WTSGetActiveConsoleSessionId() API可以得到当前激活用户的session id。每一个用户都有一个唯一的session id。
OpenProcessToken去根据这个进程句柄得到一个Token句柄。
下面是代码,最关键是看StartApplication这个函数,它是对外的唯一接口。
参考链接:http://www.codeproject.com/KB/vista-security/SubvertingVistaUAC.aspx
Service里面运行程序" border=0 alt="" align=absMiddle src="https://www.cnblogs.com/therock/admin/" width=7 height=7>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Security;
namespace Common
{
public class StartAppUtil
{
#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;