在windows系统中,有时需要在程序中以其他用户身份运行另外的exe程序,需要用
到advapi32.dll中的CreateProcessAsUser函数,在msdn中该函数原型为:
BOOL CreateProcessAsUser(
 HANDLE hToken,
 LPCTSTR lpApplicationName,
 LPTSTR lpCommandLine,
 LPSECURITY_ATTRIBUTES lpProcessAttributes,
 LPSECURITY_ATTRIBUTES lpThreadAttributes,
 BOOL bInheritHandles,
 DWORD dwCreationFlags,
 LPVOID lpEnvironment,
 LPCTSTR lpCurrentDirectory,
 LPSTARTUPINFO lpStartupInfo,
 LPPROCESS_INFORMATION lpProcessInformation);关于个参数的具体说明msdn上有详细说明
就不在这里重复了。
需要提出说明的是hToken参数,在使用这个函数的时候,token 需要采用DuplicateTokenEx
函数来复制当前的token否则会出现1349的错误。关于DuplicateTokenEx的具体说明请参阅msdn.
示列代码:
  1 using System;
  2 using System.Collections;
  3 using System.Diagnostics;
  4 using System.Threading;
  5 using Microsoft.Win32;
  6 using System.Text;
  7 using System.Security.Principal;
  8 using ReportManagerControlLibrary;
  9 using System.IO;
 10 using System.Security;
 11 using System.Security.Permissions;
 12 using System.Runtime.InteropServices;
 13 namespace  test{
 14 
 15 
 16     /// <summary>
 17     /// Add Windows authorization by Junyi ,Oct.18.2006
 18     /// </summary>
 19     [SecurityPermission(SecurityAction.Demand,ControlPrincipal = true)]
 20     public class SchematicGenerator {
 21         #region API calling
 22         [DllImport("kernel32.dll")]
 23         private static extern bool GetExitCodeProcess(IntPtr hProcess, out uint
 24             lpExitCode);
 25 
 26         [DllImport("kernel32", SetLastError=true, ExactSpelling=true)]
 27         private static extern Int32 WaitForSingleObject(IntPtr handle, Int32
 28             milliseconds);
 29 
 30         [DllImport("kernel32.dll", EntryPoint="CloseHandle", SetLastError=true,
 31              CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
 32         private extern static bool CloseHandle(IntPtr handle);
 33         [DllImport("kernel32.dll", SetLastError=true)]
 34         private extern static void ExitProcess(uint uExitCode);
 35          [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
 36         static extern Boolean CreateProcessAsUser(
 37              IntPtr hToken,
 38              String lpApplicationName,
 39              String lpCommandLine,
 40              IntPtr lpProcessAttributes,
 41              IntPtr lpThreadAttributes,
 42              Boolean bInheritHandles,
 43              UInt32 dwCreationFlags,
 44              IntPtr lpEnvironment,
 45              String lpCurrentDirectory,
 46              ref STARTUPINFO lpStartupInfo,
 47              out PROCESS_INFORMATION lpProcessInformation);
 48         [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
 49         internal static extern bool DuplicateTokenEx(IntPtr tokenHandle, int
 50             dwDesiredAccess,
 51             ref SECURITY_ATTRIBUTES lpTokenAttributes, int
 52             SECURITY_IMPERSONATION_LEVEL ,
 53             int TOKEN_TYPE, ref IntPtr dupeTokenHandle);
 54         [DllImport("kernel32.dll", SetLastError=true)]//copy user token
 55         public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle,
 56             IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr
 57 
 58 lpTargetHandle,
 59             uint dwDesiredAccess, bool bInheritHandle, uint dwOptions);
 60       
 61         [StructLayout(LayoutKind.Sequential)]
 62             internal struct SECURITY_ATTRIBUTES
 63         {
 64             internal int nLength;
 65             internal int lpSecurityDescriptor;
 66             internal bool bInheritHandle;
 67 
 68         }
 69 
 70         [StructLayout(LayoutKind.Sequential)]
 71             internal struct STARTUPINFO
 72         {
 73             internal int cb;
 74             [MarshalAs(UnmanagedType.LPTStr)]
 75             internal string lpReserved;
 76             [MarshalAs(UnmanagedType.LPTStr)]
 77             internal string lpDesktop;
 78             [MarshalAs(UnmanagedType.LPTStr)]
 79             internal string lpTitle;
 80             internal int dwX;
 81             internal int dwY;
 82             internal int dwXSize;
 83             internal int dwYSize;
 84             internal int dwXCountChars;
 85             internal int dwYCountChars;
 86             internal int dwFillAttribute;
 87             internal int dwFlags;
 88             internal short wShowWindow;
 89             internal short cbReserved2;
 90             internal IntPtr lpReserved2;
 91             internal IntPtr hStdInput;
 92             internal IntPtr hStdOutput;
 93             internal IntPtr hStdError;
 94         }
 95 
 96         [StructLayout(LayoutKind.Sequential)]
 97             internal struct PROCESS_INFORMATION
 98         {
 99             internal IntPtr hProcess;
100             internal IntPtr hThread;
101             internal int dwProcessId;
102             internal int dwThreadId;
103         }
104 
105         // SECURITY_IMPERSONATION_LEVEL
106         const int SecurityAnonymous = 0;
107         const int SecurityIdentification = 1;
108         const int SecurityImpersonation = 2;
109         const int SecurityDelegation = 3;
110 
111         // TOKEN_TYPE
112         const int TokenPrimary = 1;
113         const int TokenImpersonation = 2;
114 
115         //dwLogonFlags Specifies the logon option
116         const int LOGON_WITH_PROFILE = 1;
117         const int LOGON_NETCREDENTIALS_ONLY = 2;
118 
119         // Access Token constants
120         const int TOKEN_ALL_ACCESS = 0x10000000;
121 
122         //dwCreationFlags - Specifies how the process is created
123         const int DETACHED_PROCESS = 0x00000008;
124         const int CREATE_NO_WINDOW = 0x08000000;
125         const int CREATE_SUSPENDED = 0x00000004;
126         const int CREATE_NEW_CONSOLE = 0x00000010;
127         const int CREATE_NEW_PROCESS_GROUP = 0x00000200;
128         const int CREATE_SEPARATE_WOW_VDM = 0x00000800;
129         const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
130         const int CREATE_DEFAULT_ERROR_MODE = 0x04000000;
131 
132         //dwCreationFlags parameter controls the new process's priority class
133         const int NORMAL_PRIORITY_CLASS = 0x00000020;
134         const int IDLE_PRIORITY_CLASS = 0x00000040;
135         const int HIGH_PRIORITY_CLASS = 0x00000080;
136         const int REALTIME_PRIORITY_CLASS = 0x00000100;
137         const int BELOW_NORMAL_PRIORITY_CLASS = 0x00004000;
138         const int ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000;
139         //dwFlags
140         // This is a bit field that determines whether certain STARTUPINFO
141         // members are used when the process creates a window.
142         // Any combination of the following values can be specified:
143         const int STARTF_USESHOWWINDOW = 0x0000000;
144         const int STARTF_USESIZE = 0x00000002;
145         const int STARTF_USEPOSITION = 0x00000004;
146         const int STARTF_USECOUNTCHARS = 0x00000008;
147         const int STARTF_USEFILLATTRIBUTE = 0x00000010;
148         const int STARTF_FORCEONFEEDBACK = 0x00000040;
149         const int STARTF_FORCEOFFFEEDBACK = 0x00000080;
150         const int STARTF_USESTDHANDLES = 0x00000100;
151         const int STARTF_USEHOTKEY = 0x00000200;
152       
153         #endregion
154         public void Test()
155         {
156           
157             {              
158 
159                 try
160                 {  
161                         IntPtr dupeTokenHandle=;
162                         IntPtr hProcess = Process.GetCurrentProcess().Handle;
163                         IntPtr _hTargetToken = IntPtr.Zero;
164                         // Setting security attributes
165                         SECURITY_ATTRIBUTES sa  = new SECURITY_ATTRIBUTES();
166                         sa.bInheritHandle       = false;
167                         sa.nLength = Marshal.SizeOf(sa);
168                         sa.lpSecurityDescriptor = 0;
169               
170                         PROCESS_INFORMATION processInfo=new PROCESS_INFORMATION();
173                         //Setting startupinfo
174                         STARTUPINFO startInfo = new STARTUPINFO();
175                         startInfo.cb = Marshal.SizeOf(startInfo);
176                         startInfo.lpDesktop="";  
177                         // Copy Token
178                         bool status =DuplicateTokenEx(dupeTokenHandle,TOKEN_ALL_ACCESS, ref                            sa, SecurityImpersonation, TokenPrimary, ref  _hTargetToken);                     
183                         if(!status)
184                         {
185                             int err1 = Marshal.GetLastWin32Error();
186                             StreamWriter sw=new StreamWriter(@"C:\log.log",true);
187                             sw.WriteLine("TokenHandle:"+err1);
188                         }
189                                       
190                         //Create ProcessAsUser
191                         bool ret = CreateProcessAsUser(
192                             _hTargetToken,
193                             exePath, // file to execute
194                             arguments, // command line
195                             IntPtr.Zero, // pointer to process
196 
197 SECURITY_ATTRIBUTES
198                             IntPtr.Zero, // pointer to thread SECURITY_ATTRIBUTES
199                             false// handles are not inheritable
200                             CREATE_NEW_CONSOLE, // creation flags
201                             IntPtr.Zero, // pointer to new environment block
202                             folder, // name of current directory
203                             ref startInfo, // pointer to STARTUPINFO structure
204                             out processInfo // receives information about new
205 
206 process
207                             );
208                         if(!ret)
209                         {
210                             int err = Marshal.GetLastWin32Error();
211                               StreamWriter sw=new
212 
213 StreamWriter(@"C:\log.log",true);
214                             sw.WriteLine("TokenHandle:"+err1);
215                         }
216                         //Wait process
217                         WaitForSingleObject( processInfo.hProcess,5 * 60 * 1000)
218                         uint ec;
219                         GetExitCodeProcess(processInfo.hProcess,out ec);
220                         if((int)ec!=0)
221                         {
222                         ExitProcess(ec);
223                       
224                         }
225                         CloseHandle(processInfo.hProcess);
226                         CloseHandle(processInfo.hThread);
227                         CloseHandle(dupeTokenHandle);
228                   
229                  
230           
231 
232                 }
233                 catch(Exception ex)
234                 {
235                  
236               
237                 }
238           
239           
240           
241             }
242         }
243    
244     }
245 
246 
247 
248
249 
250 


posted on 2006-10-19 15:53  Duan Junyi   阅读(6604)  评论(2编辑  收藏  举报