CreateProcessAsUser在c#中的调用

在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 


你可能感兴趣的:(process)