在windows server 2008,Vista,win7中建立带界面的服务程序
using System; using System.Runtime.InteropServices; using System.Security.Principal; using System.Diagnostics; //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); } }