zoukankan      html  css  js  c++  java
  • [C#.Net]Window服务调用外部程序

    最近遇到要做回传服务内增加开关,可以自定义运行一些脚本已方便收集PC状态,发现Bat始终无法运行,上网找了半天才发现和Session0有关,也就是程序有不同级别的访问权限,Vista以上版本为了安全因素,限制了不同Session间的访问,可以使用Windows API还直接穿透Session0,也就是获得最高权限

    相关类如下

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Runtime.InteropServices;
      5 using System.Security.Principal;
      6 using System.Text;
      7 
      8 namespace IctInfo
      9 {
     10     /// <summary>
     11     /// 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离
     12     /// </summary>
     13     public class Interop
     14     {
     15         public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
     16 
     17         public static void ShowMessageBox(string message, string title)
     18         {
     19             int resp = 0;
     20             WTSSendMessage(
     21                 WTS_CURRENT_SERVER_HANDLE,
     22                 WTSGetActiveConsoleSessionId(),
     23                 title, title.Length,
     24                 message, message.Length,
     25                 0, 0, out resp, false);
     26         }
     27 
     28         [DllImport("kernel32.dll", SetLastError = true)]
     29         public static extern int WTSGetActiveConsoleSessionId();
     30 
     31         [DllImport("wtsapi32.dll", SetLastError = true)]
     32         public static extern bool WTSSendMessage(
     33             IntPtr hServer,
     34             int SessionId,
     35             String pTitle,
     36             int TitleLength,
     37             String pMessage,
     38             int MessageLength,
     39             int Style,
     40             int Timeout,
     41             out int pResponse,
     42             bool bWait);
     43         //在ShowMessageBox 函数中调用了WTSSendMessage 来发送信息窗口,这样我们就可以在Service 的OnStart 函数中使用,打开Service1.cs 加入下面代码:
     44         public static void CreateProcess(string app, string path)
     45         {
     46             bool result;
     47             IntPtr hToken = WindowsIdentity.GetCurrent().Token;
     48             IntPtr hDupedToken = IntPtr.Zero;
     49 
     50             PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
     51             SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
     52             sa.Length = Marshal.SizeOf(sa);
     53 
     54             STARTUPINFO si = new STARTUPINFO();
     55             si.cb = Marshal.SizeOf(si);
     56 
     57             int dwSessionID = WTSGetActiveConsoleSessionId();
     58             result = WTSQueryUserToken(dwSessionID, out hToken);
     59 
     60             if (!result)
     61             {
     62                 ShowMessageBox("WTSQueryUserToken failed", "AlertService Message");
     63             }
     64 
     65             result = DuplicateTokenEx(
     66                   hToken,
     67                   GENERIC_ALL_ACCESS,
     68                   ref sa,
     69                   (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
     70                   (int)TOKEN_TYPE.TokenPrimary,
     71                   ref hDupedToken
     72                );
     73 
     74             if (!result)
     75             {
     76                 ShowMessageBox("DuplicateTokenEx failed", "AlertService Message");
     77             }
     78 
     79             IntPtr lpEnvironment = IntPtr.Zero;
     80             result = CreateEnvironmentBlock(out lpEnvironment, hDupedToken, false);
     81 
     82             if (!result)
     83             {
     84                 ShowMessageBox("CreateEnvironmentBlock failed", "AlertService Message");
     85             }
     86 
     87             result = CreateProcessAsUser(
     88                                  hDupedToken,
     89                                  app,
     90                                  String.Empty,
     91                                  ref sa, ref sa,
     92                                  false, 0, IntPtr.Zero,
     93                                  path, ref si, ref pi);
     94 
     95             if (!result)
     96             {
     97                 int error = Marshal.GetLastWin32Error();
     98                 string message = String.Format("CreateProcessAsUser Error: {0}", error);
     99                 ShowMessageBox(message, "AlertService Message");
    100             }
    101 
    102             if (pi.hProcess != IntPtr.Zero)
    103                 CloseHandle(pi.hProcess);
    104             if (pi.hThread != IntPtr.Zero)
    105                 CloseHandle(pi.hThread);
    106             if (hDupedToken != IntPtr.Zero)
    107                 CloseHandle(hDupedToken);
    108         }
    109 
    110         [StructLayout(LayoutKind.Sequential)]
    111         public struct STARTUPINFO
    112         {
    113             public Int32 cb;
    114             public string lpReserved;
    115             public string lpDesktop;
    116             public string lpTitle;
    117             public Int32 dwX;
    118             public Int32 dwY;
    119             public Int32 dwXSize;
    120             public Int32 dwXCountChars;
    121             public Int32 dwYCountChars;
    122             public Int32 dwFillAttribute;
    123             public Int32 dwFlags;
    124             public Int16 wShowWindow;
    125             public Int16 cbReserved2;
    126             public IntPtr lpReserved2;
    127             public IntPtr hStdInput;
    128             public IntPtr hStdOutput;
    129             public IntPtr hStdError;
    130         }
    131 
    132         [StructLayout(LayoutKind.Sequential)]
    133         public struct PROCESS_INFORMATION
    134         {
    135             public IntPtr hProcess;
    136             public IntPtr hThread;
    137             public Int32 dwProcessID;
    138             public Int32 dwThreadID;
    139         }
    140 
    141         [StructLayout(LayoutKind.Sequential)]
    142         public struct SECURITY_ATTRIBUTES
    143         {
    144             public Int32 Length;
    145             public IntPtr lpSecurityDescriptor;
    146             public bool bInheritHandle;
    147         }
    148 
    149         public enum SECURITY_IMPERSONATION_LEVEL
    150         {
    151             SecurityAnonymous,
    152             SecurityIdentification,
    153             SecurityImpersonation,
    154             SecurityDelegation
    155         }
    156 
    157         public enum TOKEN_TYPE
    158         {
    159             TokenPrimary = 1,
    160             TokenImpersonation
    161         }
    162 
    163         public const int GENERIC_ALL_ACCESS = 0x10000000;
    164 
    165         [DllImport("kernel32.dll", SetLastError = true,
    166             CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    167         public static extern bool CloseHandle(IntPtr handle);
    168 
    169         [DllImport("advapi32.dll", SetLastError = true,
    170             CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
    171         public static extern bool CreateProcessAsUser(
    172             IntPtr hToken,
    173             string lpApplicationName,
    174             string lpCommandLine,
    175             ref SECURITY_ATTRIBUTES lpProcessAttributes,
    176             ref SECURITY_ATTRIBUTES lpThreadAttributes,
    177             bool bInheritHandle,
    178             Int32 dwCreationFlags,
    179             IntPtr lpEnvrionment,
    180             string lpCurrentDirectory,
    181             ref STARTUPINFO lpStartupInfo,
    182             ref PROCESS_INFORMATION lpProcessInformation);
    183 
    184         [DllImport("advapi32.dll", SetLastError = true)]
    185         public static extern bool DuplicateTokenEx(
    186             IntPtr hExistingToken,
    187             Int32 dwDesiredAccess,
    188             ref SECURITY_ATTRIBUTES lpThreadAttributes,
    189             Int32 ImpersonationLevel,
    190             Int32 dwTokenType,
    191             ref IntPtr phNewToken);
    192 
    193         [DllImport("wtsapi32.dll", SetLastError = true)]
    194         public static extern bool WTSQueryUserToken(
    195             Int32 sessionId,
    196             out IntPtr Token);
    197 
    198         [DllImport("userenv.dll", SetLastError = true)]
    199         static extern bool CreateEnvironmentBlock(
    200             out IntPtr lpEnvironment,
    201             IntPtr hToken,
    202             bool bInherit);
    203 
    204     }
    205 }

    特别感谢以下大牛的技术分享

    解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

    穿透Session 0 隔离

  • 相关阅读:
    使用Eclipse的坑
    约定优于配置
    Tomcat服务器使用和debug
    spring框架排错
    spring框架学习感悟
    Spring的标签和验证等模块
    11. Container With Most Water
    1367. Linked List in Binary Tree
    486. Predict the Winner
    205. Isomorphic Strings
  • 原文地址:https://www.cnblogs.com/masonlu/p/10279836.html
Copyright © 2011-2022 走看看