我正在开发一个使用Selenium来控制浏览器的应用程序. Selenium在初始化时启动浏览器,因此我从不直接在浏览器的.exe上调用Process.Start.我希望Selenium及其所有子进程在不同于我的应用程序的用户下运行(因为我不希望它访问我的源代码).使用模拟样本
here,我试图用模拟包装Selenium代码,但似乎所有子进程都由启动其父进程的用户启动.
有没有人知道用户模仿包装代码块的方法,并使用模拟用户的权限启动所有子进程?如果没有,那么实现这一目标的最佳策略是什么?在另一个进程中运行所有Selenium逻辑并以某种方式管道命令到它?
解决方法
试试这个 .
本课程使您能够以用户身份进行午餐过程,
在这里,我使用Explorer会话.
using System.Runtime.InteropServices; using System; using System.Diagnostics; [StructLayout(LayoutKind.Sequential)] internal struct PROCESS_@R_128_4045@ION { public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId; } [StructLayout(LayoutKind.Sequential)] internal struct Security_ATTRIBUTES { public uint nLength; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; } [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO { public uint 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; } internal enum Security_IMPERSONATION_LEVEL { SecurityAnonymous,SecurityIdentification,SecurityImpersonation,SecurityDelegation } internal enum TOKEN_TYPE { TokenPrimary = 1,TokenImpersonation } public class ProcessAsUser { [DllImport("advapi32.dll",SetLastError = true)] private static extern bool CreateProcessAsUser( IntPtr hToken,string lpApplicationName,string lpCommandLine,ref Security_ATTRIBUTES lpProcessAttributes,ref Security_ATTRIBUTES lpThreadAttributes,bool bInheritHandles,uint dwCreationFlags,IntPtr lpEnvironment,string lpCurrentDirectory,ref STARTUPINFO lpStartupInfo,out PROCESS_@R_128_4045@ION lpProcess@R_128_4045@ion); [DllImport("advapi32.dll",EntryPoint = "DuplicatetokenEx",SetLastError = true)] private static extern bool DuplicatetokenEx( IntPtr hExistingToken,uint dwDesiredAccess,Int32 ImpersonationLevel,Int32 dwTokenType,ref IntPtr phNewToken); [DllImport("advapi32.dll",SetLastError = true)] private static extern bool OpenProcesstoken( IntPtr ProcessHandle,UInt32 DesiredAccess,ref IntPtr TokenHandle); [DllImport("userenv.dll",SetLastError = true)] private static extern bool CreateEnvironmentBlock( ref IntPtr lpEnvironment,IntPtr hToken,bool bInherit); [DllImport("userenv.dll",SetLastError = true)] private static extern bool DestroyEnvironmentBlock( IntPtr lpEnvironment); [DllImport("kernel32.dll",SetLastError = true)] private static extern bool CloseHandle( IntPtr hObject); private const short SW_SHOW = 5; private const uint TOKEN_QUERY = 0x0008; private const uint TOKEN_DUPLICATE = 0x0002; private const uint TOKEN_ASSIGN_PRIMARY = 0x0001; private const int GENERIC_ALL_ACCESS = 0x10000000; private const int STARTF_USESHOWWINDOW = 0x00000001; private const int STARTF_FORCEONFeedBACK = 0x00000040; private const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400; private static bool LaunchProcessAsUser(string cmdLine,IntPtr token,IntPtr envBlock) { bool result = false; PROCESS_@R_128_4045@ION pi = new PROCESS_@R_128_4045@ION(); Security_ATTRIBUTES saProcess = new Security_ATTRIBUTES(); Security_ATTRIBUTES saThread = new Security_ATTRIBUTES(); saProcess.nLength = (uint)Marshal.SizeOf(saProcess); saThread.nLength = (uint)Marshal.SizeOf(saThread); STARTUPINFO si = new STARTUPINFO(); si.cb = (uint)Marshal.SizeOf(si); //if this member is NULL,the new process inherits the desktop //and window station of its parent process. If this member is //an empty string,the process does not inherit the desktop and //window station of its parent process; instead,the system //determines if a new desktop and window station need to be created. //If the impersonated user already has a desktop,the system uses the //existing desktop. si.lpDesktop = @"WinSta0\Default"; //Modify as needed si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFeedBACK; si.wShowWindow = SW_SHOW; //Set other si properties as required. result = CreateProcessAsUser( token,null,cmdLine,ref saProcess,ref saThread,false,CREATE_UNICODE_ENVIRONMENT,envBlock,ref si,out pi); if (result == false) { int error = Marshal.GetLastWin32Error(); string message = String.Format("CreateProcessAsUser Error: {0}",error); Debug.WriteLine(message); } return result; } private static IntPtr GetPrimaryToken(int processId) { IntPtr token = IntPtr.Zero; IntPtr primaryToken = IntPtr.Zero; bool retVal = false; Process p = null; try { p = Process.GetProcessById(processId); } catch (ArgumentException) { string details = String.Format("ProcessID {0} Not Available",processId); Debug.WriteLine(details); throw; } //Gets impersonation token retVal = OpenProcesstoken(p.Handle,TOKEN_DUPLICATE,ref token); if (retVal == true) { Security_ATTRIBUTES sa = new Security_ATTRIBUTES(); sa.nLength = (uint)Marshal.SizeOf(sa); //Convert the impersonation token into Primary token retVal = DuplicatetokenEx( token,TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY,ref sa,(int)Security_IMPERSONATION_LEVEL.SecurityIdentification,(int)TOKEN_TYPE.TokenPrimary,ref primaryToken); //Close the Token that was prevIoUsly opened. CloseHandle(token); if (retVal == false) { string message = String.Format("DuplicatetokenEx Error: {0}",Marshal.GetLastWin32Error()); Debug.WriteLine(message); } } else { string message = String.Format("OpenProcesstoken Error: {0}",Marshal.GetLastWin32Error()); Debug.WriteLine(message); } //We'll Close this token after it is used. return primaryToken; } private static IntPtr GetEnvironmentBlock(IntPtr token) { IntPtr envBlock = IntPtr.Zero; bool retVal = CreateEnvironmentBlock(ref envBlock,token,false); if (retVal == false) { //Environment Block,things like common paths to My Documents etc. //Will not be created if "false" //It should not adversley affect CreateProcessAsUser. string message = String.Format("CreateEnvironmentBlock Error: {0}",Marshal.GetLastWin32Error()); Debug.WriteLine(message); } return envBlock; } public static bool Launch(string appCmdLine /*,int processId*/) { bool ret = false; //Either specify the processID explicitly //Or try to get it from a process owned by the user. //In this case assuming there is only one explorer.exe Process[] ps = Process.GetProcessesByName("explorer"); int processId = -1;//=processId if (ps.Length > 0) { processId = ps[0].Id; } if (processId > 1) { IntPtr token = GetPrimaryToken(processId); if (token != IntPtr.Zero) { IntPtr envBlock = GetEnvironmentBlock(token); ret = LaunchProcessAsUser(appCmdLine,envBlock); if (envBlock != IntPtr.Zero) DestroyEnvironmentBlock(envBlock); CloseHandle(token); } } return ret; }
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。