在windows server 2008,Vista,win7中建立带界面的服务程序
//Requirements
//Minimum supported client
//Windows 2000 Professional
//Minimum supported server
//Windows 2000 Server
//Header
//Winbase.h (include Windows.h)
//Library
//Advapi32.lib
//DLL
//Advapi32.dll
//BOOL WINAPI SetTokenInformation(
// __in HANDLE TokenHandle,
// __in TOKEN_INFORMATION_CLASS TokenInformationClass,
// __in LPVOID TokenInformation,
// __in DWORD TokenInformationLength
//);
namespace TestWindowsServiceServer2008
{
class Interop
{
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);
[DllImport("Advapi32.dll",SetLastError = true)]
public static extern bool SetTokenInformation(
IntPtr TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
ref int TokenInformation,
int TokenInformationLength);
//********************************
public struct LUID
{
public int LowPart;
public int HighPart;
}
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public int Attributes;
}
public struct TOKEN_PRIVILEGES
{
public int PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 1)]
public LUID_AND_ATTRIBUTES[] Privileges;
}
//
// Token Specific Access Rights.
//
public static int TOKEN_ASSIGN_PRIMARY = 0x0001;
public static int TOKEN_DUPLICATE = 0x0002;
public static int TOKEN_IMPERSONATE = 0x0004;
public static int TOKEN_QUERY = 0x0008;
public static int TOKEN_QUERY_SOURCE = 0x0010;
public static int TOKEN_ADJUST_PRIVILEGES = 0x0020;
public static int TOKEN_ADJUST_GROUPS = 0x0040;
public static int TOKEN_ADJUST_DEFAULT = 0x0080;
public static int TOKEN_ADJUST_SESSIONID = 0x0100;
public static int MAXIMUM_ALLOWED = 0x02000000;
// begin_ntddk begin_nthal begin_ntifs
//
// Privilege attributes
//
public static int SE_PRIVILEGE_ENABLED = 0x00000002;
//BOOL WINAPI LookupPrivilegeValue
// (
// __in_opt LPCTSTR lpSystemName,
// __in LPCTSTR lpName,
// __out PLUID lpLuid
// );
//BOOL OpenProcessToken
//(
// HANDLE ProcessHandle, //要修改访问权限的进程句柄
// DWORD DesiredAccess, //指定你要进行的操作类型
// PHANDLE TokenHandle //返回的访问令牌指针
//)
//BOOL WINAPI AdjustTokenPrivileges(
// __in HANDLE TokenHandle,
// __in BOOL DisableAllPrivileges,
// __in_opt PTOKEN_PRIVILEGES NewState,
// __in DWORD BufferLength,
// __out_opt PTOKEN_PRIVILEGES PreviousState,
// __out_opt PDWORD ReturnLength
//)
//HANDLE WINAPI OpenProcess(
// __in DWORD dwDesiredAccess,
// __in BOOL bInheritHandle,
// __in DWORD dwProcessId
//);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(
int dwDesiredAccess,
bool bInheritHandle,
int dwProcessId
);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool OpenProcessToken([In] IntPtr ProcessToken, [In] TokenAccessLevels DesiredAccess, [In, Out] ref IntPtr TokenHandle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool LookupPrivilegeValue([MarshalAs(UnmanagedType.LPTStr)] string lpSystemName, [MarshalAs(UnmanagedType.LPTStr)] string lpName, out LUID lpLuid);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, TOKEN_PRIVILEGES NewState, int BufferLength, IntPtr PreviousState, IntPtr ReturnLength);
// GetDebugPriv
public static bool GetDebugPriv(int dwExplorerLogonPid)
{
IntPtr hToken = IntPtr.Zero;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
IntPtr hProcess = OpenProcess(MAXIMUM_ALLOWED,false,Process.GetCurrentProcess().Id);
if (!OpenProcessToken(hProcess, TokenAccessLevels.AdjustPrivileges | TokenAccessLevels.Query, ref hToken))
{
int error = Marshal.GetLastWin32Error();
string message = String.Format("OpenProcessToken Error: {0}", error);
ShowMessageBox(message, "AlertService Message");
return false;
}
if ( ! LookupPrivilegeValue( null, "SeDebugPrivilege", out sedebugnameValue ) ) // advapi32.dll
{
int error = Marshal.GetLastWin32Error();
string message = String.Format("LookupPrivilegeValue Error: {0}", error);
ShowMessageBox(message, "AlertService Message");
CloseHandle( hToken );
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges = new LUID_AND_ATTRIBUTES[1];
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, false, tkp, Marshal.SizeOf(tkp), IntPtr.Zero, IntPtr.Zero))
{
int error = Marshal.GetLastWin32Error();
string message = String.Format("AdjustTokenPrivileges Error: {0}", error);
ShowMessageBox(message, "AlertService Message");
CloseHandle( hToken );
return false;
}
return true;
}
//********************************
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();
// if (!GetDebugPriv(dwSessionID))
// {
// return;
// }
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");
}
//if (!SetTokenInformation(hDupedToken, TOKEN_INFORMATION_CLASS.TokenSessionId, ref dwSessionID, sizeof(int)))
//{
// int error = Marshal.GetLastWin32Error();
// string message = String.Format("SetTokenInformation Error: {0}", error);
// ShowMessageBox(message, "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, // lpEnvironment,(加这个参数以后,出错,错误代码:87(不正确的参数),为什么?)
path,
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);
}
public enum TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
MaxTokenInfoClass
}
[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);
}
}