65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 C# 编写的服务辅助应用程序将您的应用程序启动到会话 1

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.39/5 (16投票s)

2007年5月13日

1分钟阅读

viewsIcon

94952

downloadIcon

2403

在本地系统帐户下,使用会话 0 中的服务(C#)将您的应用程序启动到会话 1。

引言

这篇文章与我之前用原生 C++ 编写的文章相同。(使用 Vista 中的服务辅助应用程序从会话 0 启动到会话 1,请参阅 VistaSessions.asp

Luzius Kalt 给我发来了一份 C# 版本的服务,对于那些希望在 .NET 平台上使用该代码的人来说,这将非常有效。

由于我收到了很多要求将文章发布在 .NET 上的请求,因此我发布了从 Luzius 处收到的代码。

为了表彰他的努力,我将此作为单独的文章发布。

使用代码

应用程序逻辑的核心是服务。这是将辅助应用程序启动到会话 1 的关键。

因此,只有服务是用 C# 重写的。

用 C# 重写的代码使用 PINVOKE 来执行原生 API。

发送消息到服务的自定义消息发送器应用程序,以及将访问注册表中的 HKCU 的代码(请参阅我的文章 VistaSessions.asp)仍然使用原生代码。

我很快会更新这些内容。

以下结构和 API 来自 Win32,已在 C# 中声明

// Structure for the CreateProcessAsuser API
[StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public int Length;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }
//Structure for the DuplicateTokenEx API
        enum TOKEN_TYPE : int
        {
            TokenPrimary = 1,
            TokenImpersonation = 2
        }
//Structure for the SetTokenInformation API
        public enum TOKEN_INFORMATION_CLASS : int
        {
            TokenUser = 1,
            TokenGroups,
            TokenPrivileges,
            TokenOwner,
            TokenPrimaryGroup,
            TokenDefaultDacl,
            TokenSource,
            TokenType,
            TokenImpersonationLevel,
            TokenStatistics,
            TokenRestrictedSids,
            TokenSessionId,
            TokenGroupsAndPrivileges,
            TokenSessionReference,
            TokenSandBoxInert,
            TokenAuditPolicy,
            TokenOrigin,
            MaxTokenInfoClass  
        // MaxTokenInfoClass should always be the last enum
        }
//Structure for CreateProcess API
        [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;
        }
//Structure for CreateProcess API
        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public uint dwProcessId;
            public uint dwThreadId;
        }
//Structure for LookupPriveleges API
       [StructLayout(LayoutKind.Sequential)]
        internal struct LUID
        {
            public int LowPart;
            public int HighPart;
        }//end struct
//For the TOKEN PRIVILEGES STRUCTURE
        [StructLayout(LayoutKind.Sequential)]
        internal struct LUID_AND_ATRIBUTES
        {
            public LUID Luid;
            public int Attributes;
        }//end struct
//Structure for the AdjustTokenPrivileges API

        [StructLayout(LayoutKind.Sequential)]
        internal struct TOKEN_PRIVILEGES
        {
            internal int PrivilegeCount;
            //LUID_AND_ATRIBUTES
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            internal int[] Privileges;
        }

//Defined for Token rights

        public const int READ_CONTROL = 0x00020000;
        public const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        public const int STANDARD_RIGHTS_READ = READ_CONTROL;
        public const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
        public const int STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
        public const int STANDARD_RIGHTS_ALL = 0x001F0000;
        public const int SPECIFIC_RIGHTS_ALL = 0x0000FFFF;
        public const int TOKEN_ASSIGN_PRIMARY = 0x0001;
        public const int TOKEN_DUPLICATE = 0x0002;
        public const int TOKEN_IMPERSONATE = 0x0004;
        public const int TOKEN_QUERY = 0x0008;
        public const int TOKEN_QUERY_SOURCE = 0x0010;
        public const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
        public const int TOKEN_ADJUST_GROUPS = 0x0040;
        public const int TOKEN_ADJUST_DEFAULT = 0x0080;
        public const int TOKEN_ADJUST_SESSIONID = 0x0100;
        public const int TOKEN_ALL_ACCESS_P = (STANDARD_RIGHTS_REQUIRED |
                                      TOKEN_ASSIGN_PRIMARY |
                                      TOKEN_DUPLICATE |
                                      TOKEN_IMPERSONATE |
                                      TOKEN_QUERY |
                                      TOKEN_QUERY_SOURCE |
                                      TOKEN_ADJUST_PRIVILEGES |
                                      TOKEN_ADJUST_GROUPS |
                                      TOKEN_ADJUST_DEFAULT);
        public const int TOKEN_ALL_ACCESS = TOKEN_ALL_ACCESS_P | 
                      TOKEN_ADJUST_SESSIONID;
        public const int TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY;
        public const int TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
                                      TOKEN_ADJUST_PRIVILEGES |
                                      TOKEN_ADJUST_GROUPS |
                                      TOKEN_ADJUST_DEFAULT;
        public const int TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE;

//Defined for Process Rights
        public const uint MAXIMUM_ALLOWED = 0x2000000;
        public const int CREATE_NEW_PROCESS_GROUP = 0x00000200;
        public const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
        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;
        public const int CREATE_NEW_CONSOLE = 0x00000010;
        public const string SE_DEBUG_NAME = "SeDebugPrivilege";
        public const string SE_RESTORE_NAME = "SeRestorePrivilege";
        public const string SE_BACKUP_NAME = "SeBackupPrivilege";
        public const int SE_PRIVILEGE_ENABLED = 0x0002;
        public const int ERROR_NOT_ALL_ASSIGNED = 1300;

//structure for the Process32First API
   
[StructLayout(LayoutKind.Sequential)]
        private struct PROCESSENTRY32
        {
            public uint dwSize;
            public uint cntUsage;
            public uint th32ProcessID;
            public IntPtr th32DefaultHeapID;
            public uint th32ModuleID;
            public uint cntThreads;
            public uint th32ParentProcessID;
            public int pcPriClassBase;
            public uint dwFlags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szExeFile;
        }      
其余代码都很简单。您可以参考我之前的文章来了解核心逻辑。您可以自由使用此代码。如有任何疑问,请通过 jaisvar@gmail.com 与我联系。我正在撰写我的第二篇文章,关于 UAC 调整,很快就会发布。
© . All rights reserved.