既然选择远方,便只顾风雨兼程……

Run As(运行方式) 的几种代码实现方式(Python和C#)

上一篇 / 下一篇  2009-05-25 16:13:00

8ea f4vT j+hW!L01,引入

QzO1t;f-@`Y051Testing软件测试网X~!e4R7F

     最近因为项目的原因,需要在自动化测试代码中实现用户角色的切换,自然第一印象就想到了Run As(中文版windows中也叫“运行方式”)。比如我们可以在打开IE浏览器的时候右键单击“运行方式”:

Lp/IV T*T4p%b0

9|9e'o4NSv8e OJ0Run AS

\Ree \ i2I{7A-g0

|/R2P7h9k}#G0然后输入一个新的用户帐户,如下图:

h.k"C_ h+J1c0

m u cR w]0 Run As51Testing软件测试网,J]JW+H6a+NV|j

51Testing软件测试网'i@oW;J

上图中我本机使用的是域帐户本地帐户登陆的操作系统,但是我现在需要使用域帐户来运行IE浏览器,以方便我在打开相应的绑定域帐户权限的页面,如公司内部站点。这样就不用在打开相应的页面时候输入域帐户名了。

n*C1h,v2Z.j#ELv0

7T xfO-s0  有些时候我们也可以应用相同的方式来使用管理员帐户启动相应的应用程序:

{w5zl` O0

i9GMV;]6[3G0Run As

?]*x*L+R051Testing软件测试网2IS | y0@!c

在较近操作系统中,右键菜单中没有了“Run as”,而是变成了“Run As Administrator”,目的是提高运行相应程序的用户权限:

iOWofM X051Testing软件测试网+b3a9Q4S.H fzI

Run AS Admin51Testing软件测试网O#S H3]'Qz

3KL L4};m#M0  好了,言归正传,今天笔者提到的则是使用代码来实现相同的功能,即以更改运行程序的用户帐户。51Testing软件测试网'L9BZ? `Dj

x ~ ?1u/a vB$L(l/J02,代码实现命令行Run As

U.}\P&rv0

6T;Dv yL$A0  命令行51Testing软件测试网q]-yy$L5Mcj

51Testing软件测试网%jJu,ZXh W$i ^zi

     用命令行实现上述的Run as功能大致可以这样写:

8l)i4b'X$G(eu*HKn051Testing软件测试网#_7i Ias

      runas /user:user@domain.com "C:\Program Files\Internet Explorer\iexplore.exe"

%PoPfMj051Testing软件测试网;V3ZgBqG7ya)s

      Python实现51Testing软件测试网 _I H1@*peC

Y ?&p'q(M0  RunAsWithinPython.py文件内容如下:51Testing软件测试网F(S7i:K U SUE

Runas Commandline in Python51Testing软件测试网'_,`Z}^ L
import os51Testing软件测试网zD d3fJ"zc K2Z
os.system(
"runas /user:user@domain.com \"C:\Program Files\Internet Explorer\iexplore.exe\"")51Testing软件测试网4_/oG[Rv U0O{
51Testing软件测试网2YS1H mP E cVGx H8R

     额,就这两行,看起来比命令行内容多不了几个字符,不得不惊诧Python的强悍。另外,python使用缩进来表示代码层次而不是我们在C#等语言中用的大括号“{”,代码看起来很爽,当然,这是闲话了。

B0C,y7U+YhdL051Testing软件测试网e)Eab5grtD

  C#实现 

\J!QJT kg*d_0

}B`*DSM8Z0      Program.cs文件内容如下:

EF]:i m*{yk0
Runas Commandline in C#51Testing软件测试网B0ybWUry
using System.Diagnostics;51Testing软件测试网8\UH3@'@!^T

{5Bz%G;{#z(MH4yE0
namespace MainTest51Testing软件测试网:zDVm ECe^P;slR
{
3z:g Y5S2h3q ^0    
class Program
t:K@+Vr,h"Qb9Q R@e0    {        
N ~&~gQ0        
public static void Main(string[] args)51Testing软件测试网Sk u h2E"w
        {
Qh [ oU}D0            System.Diagnostics.Process cmd 
= System.Diagnostics.Process.Start("runas"51Testing软件测试网yG[ G(V
                
"/user:user@domain.com  \"C:\\Program Files\\Internet Explorer\\iexplore.exe\"");
*v](_*o&y z&F+X0        }51Testing软件测试网H4H f6T:L7r
    }
@$s!\(k)B0}
51Testing软件测试网Ohuo `-qc7L'Oc8BT

   恩,C#表现也不错,看来确实是一个比较简单的命令而已,如果你没有运行一下这两个程序,你可能以为这样就搞定了,相当简单。但是如果你是一个细心的人,或者你是用过runas命令行的话,你应该知道,这里有问题:51Testing软件测试网+PX/v)T+}/y F Rz s

51Testing软件测试网 g E l$H I)t9p~ ~ I

      很可惜的是,这两种方式存在一个致命的缺陷:只能在第一个命令行中输入用户名,然后才会由系统提示输入密码,这样就不能在一条命令行中将用户名和密码完全包含。这样我们只能使用代码实现一半,另外一半则仍然需要手动输入(密码)——显然这就造成了一个半拉子工程。我们也可以查看一下runas帮助说明:

eC:@k7F051Testing软件测试网z,N&}'E.~K:TmY

Runas Helper

z1T]Kg-ik0

,m*W kTNEY0  这样设计的目的在于防止像我们这种弱弱的想要使用命令行来提高运行程序的权限的人——至少我们是不能使用批处理文件来干这件事了,这样更安全了,不是吗?好吧,接下来,我们将使用另外一种方法,这种方法则不会出现上述半拉子工程的尴尬情况。51Testing软件测试网1zK}f'fc.w#y h)Mb{

51Testing软件测试网#Bt4`cxNI/Y

3, 使用Process的ProcessStartInfo实现51Testing软件测试网Owc5G$Ygfxq6E

m"m _0]"z0

h1VEXQ6h F({0
ProcessUserLogonHelper51Testing软件测试网f_L~hnU
using System;
v'JM g;^0
using System.Collections.Generic;
:d @7HLp&F-eZ.G5Y\0
using System.Linq;
"l AIlH;mAk;W0
using System.Text;51Testing软件测试网Q!@*fP0jU
using System.Diagnostics;
;Q:nJjs _;^$xH0
P,]}F7zP6q0
namespace MainTest51Testing软件测试网U [B9v.V:Q:T$G1I
{
#oP Sx0I%Cl0    
class ProcessUserLogonHelper
#J}uu ig|0    {
G K R(]L0        
/// <summary>51Testing软件测试网8C9u A,f@2`[SL!PW
        
/// 在Main函数中调用该方法的的示例代码
5YC Yg?}5j0        
/// </summary>51Testing软件测试网,ti1k1J4B,`O q s.Z
        private void InvokeExample()51Testing软件测试网d g pd}`'T!H
        {
U%agc` o"Qb0            ProcessUserLogonHelper phelper 
= new ProcessUserLogonHelper();
q`~ @LI,]8b1|G0            Process pro 
= phelper.CreateProcessWithUserToken(@"C:\Program Files\Internet Explorer\iexplore.exe""bestreme.com""chdwu""************");
T p:JIN [ m0            pro.Start();51Testing软件测试网r{)@,S(x9lk2w;H
        }
$u S v fM}F-E0
RG1z xd+{$}0s'Nvo0        /// <summary>
?iOgF+d0        /// 使用指定帐户绑定进程
XD3X `7P$dI.Y#Y _\0        /// </summary>51Testing软件测试网L K*|J k] y TH
        /// <param name="appPath">进程的宿主程序</param>51Testing软件测试网U8RQh9\t+z;QH
        /// <param name="domain">指定帐户的域名</param>51Testing软件测试网(]a!R,T%Kjr7F
        /// <param name="userName">指定帐户的用户名</param>
H6AM#ba?z#L0        /// <param name="password">指定帐户的密码</param>
0}#u0nm_DN0        /// <returns>绑定了特定帐户的进程</returns>
4S[R:bWIxiR4~O0        public Process CreateProcessWithUserToken(string appPath,string domain, string userName, string password)51Testing软件测试网E'T6N?K0]^
        {
C$uX'qe$y t0            Process pro = new Process();51Testing软件测试网l_F E vN"?0h%j
            ProcessStartInfo processInfo = new ProcessStartInfo(appPath);51Testing软件测试网 NSC;pa k_,V)q#@g
            processInfo.UseShellExecute = false;51Testing软件测试网(w"M&j!W%kz,}
            processInfo.UserName = userName;
2X\9S ^C-F-?-e F0            processInfo.Domain = domain;
iWUN"^Q0x V0HOY0            System.Security.SecureString psw = new System.Security.SecureString();
AS&[ Oi0            foreach (char c in password.ToCharArray())
sM4e7h:G*J.q0            {
:j.A c~\n/NF0                psw.AppendChar(c);
7_ kax;HI1u0            }
-S@-u`foJ0            processInfo.Password = psw;
K(h ki'S G6LLM0            processInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(appPath);51Testing软件测试网kO[/[;@GX
            pro.StartInfo = processInfo;
:ZtG3m3JqZr0            return pro;51Testing软件测试网A#Sx;{z&@3Y%K&N*}
        }
k7d7T"e5~)_KT0
wX },b"q yS Cbb$F0        /// <summary>
5~w.`.iDt H\ K0        /// 使用指定帐户绑定进程
(}#["_7XDiP6i0        /// </summary>51Testing软件测试网)ph@+q&|9{B$v`4`q!o
        /// <param name="appPath">进程的宿主程序</param>
Iq*pht&aG_0        /// <param name="userName">指定本地帐户的用户名</param>51Testing软件测试网,V6R9WWZ hF
        /// <param name="password">指定帐户的密码</param>51Testing软件测试网!V0?9G7US%\*C l6e!{Qr
        /// <returns>绑定了特定帐户的进程</returns>
6]&gh w a&rV;f0        public Process CreateProcessWithUserToken(string appPath, string userName, string password)
,D }(u?2KM#}#N G0        {51Testing软件测试网+pTs,dV
            return CreateProcessWithUserToken(appPath, "", userName, password);
6b P yW1?6|J+M:lr0        }51Testing软件测试网@m;gN Eb3q
    }51Testing软件测试网 ^-OiuOr
}51Testing软件测试网.| _oZu0P

T[^@ [2gZD#zX0    上面的代码有几个地方需要指出的是:

7aP&ON c:R3Ao R7A0

5C)F pyz9C5N!RB0M0    1, 应该待运行的程序指定相应的启动路径,否则的话在上述代码运行的过程中可能提示“目录不存在”;

5Ys` le1N:fM,pG0

&Kb#] ]|NU,f!f0    2,Domain可以不设置,而直接使用bestreme\chdwu的方式给UserName赋值即可;51Testing软件测试网D P|7a5isFMZN

51Testing软件测试网n/a#~Z7{$i~kW

     3,UseShellExecute 应该设置为False51Testing软件测试网V4iL5]IVs ?Y+Ho

51Testing软件测试网TPjw$Wt |"nS

     4,ProcessStartInfo中的password是System.Security.SecureString类型的,所以如果我们只是传入了一个string作为password,我们应该将其转换为正确的类型。

\)_ jq5E)k j0

3gc&B B&S0结束语

Mr }1P,Sh0

!["ea1R6Xw0  上面为大家介绍了几种Run as的实现方式,其中的前面两种分别用Python和C#实现了命令行Run as的功能,第三种方法则是在ProcessStartInfo中加入了用户信息以实现用指定用户启动运行应用程序。51Testing软件测试网-wp w [YA"`

1c7n$A[b#iQ0     当然实现Run as的代码实现方法很多,在下一篇中将介绍一下有关使用Win32 API的实现。需要指出的是,使用Win32 API几种实现方式存在着一些潜在的问题,详细内容将尽快在下一篇文章中给大家展示。51Testing软件测试网L u5Z'y*q


TAG:

 

评分:0

我来说两句

Open Toolbar