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

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

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

51Testing软件测试网7b7@ v(K]n5]

1,引入

R w `3S9NA051Testing软件测试网7X9Kxy;Bd

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

51Testing软件测试网 o_*j#^T+q0hw4lT

Run AS

7hZY7}G051Testing软件测试网dv*E6RRk

然后输入一个新的用户帐户,如下图:

oyb!t?;pl+R7\ u#iNI0

N|\E1xy0 Run As51Testing软件测试网 }kY_(NDf

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

0ncwQU R(?0x Y0

H5['KWSMl0  有些时候我们也可以应用相同的方式来使用管理员帐户启动相应的应用程序:

pm;s:DG1wNRQ.}0

0K/Y@W Rh M0t"A"I&yy0Run As

Q`W"Y*\"[D051Testing软件测试网 YI)\/?sg9B2wL

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

5F]Q@!u)Ch0

(EbH'do(p"y0Run AS Admin

8e#CY*l`0

5g9S^f0v&k*rNw%q0  好了,言归正传,今天笔者提到的则是使用代码来实现相同的功能,即以更改运行程序的用户帐户。

z2cf7J.pA051Testing软件测试网2Fmt1s+H(zxKilr

2,代码实现命令行Run As51Testing软件测试网 P9VJk*`o

7B8CSB*E*~+`w0  命令行51Testing软件测试网 q Ur2A.L7V

*df p7g!EE A0     用命令行实现上述的Run as功能大致可以这样写:

P Dd G0M-By0

C6PL jpr6e#apB0      runas /user:user@domain.com "C:\Program Files\Internet Explorer\iexplore.exe"51Testing软件测试网czs\"B/k6k CZ

%Z I2V R/Ta0      Python实现

o~W|)jO051Testing软件测试网q-DB"I d/@K

  RunAsWithinPython.py文件内容如下:

T7]h;o;F*st:l4R0
Runas Commandline in Python51Testing软件测试网Z/s jYY8z(nX
import os
$|AdWC"o{Y2y F]5K0os.system(
"runas /user:user@domain.com \"C:\Program Files\Internet Explorer\iexplore.exe\"")51Testing软件测试网(P~ Y3u zaW
51Testing软件测试网?"d|2B\Q.U;_#w"M2_

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

!l{F`_3G\HK051Testing软件测试网 R0A*M'V,yo%E o |

  C#实现 51Testing软件测试网QcB/~pg-N U+q

1WP8A/[{gW:f U,N%s0      Program.cs文件内容如下:51Testing软件测试网d(|\er%niH\wp |

Runas Commandline in C#
!W9a7O\-B)ge:`+ORFa0using System.Diagnostics;
0wf7y+f)H0
+I J x2wxbV0
namespace MainTest51Testing软件测试网nWC:Fe6mOq
{
z V(x;Aek7?hF0    
class Program51Testing软件测试网 Ter?m%Fie
    {        51Testing软件测试网"St"} eeLo E6?
        
public static void Main(string[] args)51Testing软件测试网-G,J o,jF
        {51Testing软件测试网3_#w\+EP?
            System.Diagnostics.Process cmd 
= System.Diagnostics.Process.Start("runas"
&m5c!T A l(~W6Mt0                
"/user:user@domain.com  \"C:\\Program Files\\Internet Explorer\\iexplore.exe\"");
L&b)[.s8R*k0        }51Testing软件测试网QM [vLU5B7M#xtT
    }51Testing软件测试网2[ a/e o$q&M
}

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

d i@u#B xq$]I0      很可惜的是,这两种方式存在一个致命的缺陷:只能在第一个命令行中输入用户名,然后才会由系统提示输入密码,这样就不能在一条命令行中将用户名和密码完全包含。这样我们只能使用代码实现一半,另外一半则仍然需要手动输入(密码)——显然这就造成了一个半拉子工程。我们也可以查看一下runas帮助说明:51Testing软件测试网:_r[N.n0Uo{

7K8Q[M)WQ0Runas Helper51Testing软件测试网)V"FH2\@5g;^6T

51Testing软件测试网vWK4Y["w/S/U

  这样设计的目的在于防止像我们这种弱弱的想要使用命令行来提高运行程序的权限的人——至少我们是不能使用批处理文件来干这件事了,这样更安全了,不是吗?好吧,接下来,我们将使用另外一种方法,这种方法则不会出现上述半拉子工程的尴尬情况。

Dh2^ tC:Gbf:I0

WI@0o/ov03, 使用Process的ProcessStartInfo实现

.C'o&F$Vm}@051Testing软件测试网B5Z#}O P

51Testing软件测试网QJ)R:k+un` z

ProcessUserLogonHelper51Testing软件测试网d6h L1cuh)H\ K*d
using System;51Testing软件测试网dt*t"z6Z9o
using System.Collections.Generic;51Testing软件测试网r-o-ve"}
using System.Linq;51Testing软件测试网|L1~2g3R7l
using System.Text;51Testing软件测试网u^ B"I EWx ?.j$Qd$]
using System.Diagnostics;
%M:l2E#@-I9mR051Testing软件测试网qIQ f%?0Ym.s |/]&@
namespace MainTest
7m'hR m\N0{
4cBb%x"O`#c N0    
class ProcessUserLogonHelper51Testing软件测试网x_dW.q0r-V+z/g7V
    {
Pb8dd k*o0        
/// <summary>
j*x ?_j!x._&{c0        
/// 在Main函数中调用该方法的的示例代码
xXb?&};ad*T:a Q0        
/// </summary>51Testing软件测试网 F G0z,k5Y%Jv$To
        private void InvokeExample()51Testing软件测试网Hf@nf I5L
        {
YZe2OcVk3K0            ProcessUserLogonHelper phelper 
= new ProcessUserLogonHelper();
ctZ"y/kx0            Process pro 
= phelper.CreateProcessWithUserToken(@"C:\Program Files\Internet Explorer\iexplore.exe""bestreme.com""chdwu""************");51Testing软件测试网+RF.n8Ku:kW
            pro.Start();51Testing软件测试网tn xKp x
        }
#v#I w!F"?kv0
(o ]!j"z9q(W+A:]0        /// <summary>51Testing软件测试网4r U1]u%bS
        /// 使用指定帐户绑定进程51Testing软件测试网f/Q#}n/Cd D
        /// </summary>
2e&A s&zv0        /// <param name="appPath">进程的宿主程序</param>51Testing软件测试网ff F`}6[
        /// <param name="domain">指定帐户的域名</param>
vz4Y\{5ZVe9?0        /// <param name="userName">指定帐户的用户名</param>51Testing软件测试网4b ]|)ZeR
        /// <param name="password">指定帐户的密码</param>
1L v5mvD#I0        /// <returns>绑定了特定帐户的进程</returns>51Testing软件测试网v } lj*e.hn2`
        public Process CreateProcessWithUserToken(string appPath,string domain, string userName, string password)51Testing软件测试网i*J/g[-y
        {51Testing软件测试网7b.P/O,A`.d.by8C
            Process pro = new Process();
Fg,^8Cb Vk0            ProcessStartInfo processInfo = new ProcessStartInfo(appPath);
\Bj bq0            processInfo.UseShellExecute = false;
4?-ED N'[5]0            processInfo.UserName = userName;51Testing软件测试网u7AU-cNzz
            processInfo.Domain = domain;
3x _&g*@5h[ q0            System.Security.SecureString psw = new System.Security.SecureString();51Testing软件测试网0d#o"x WB AF fWu
            foreach (char c in password.ToCharArray())
|C;JKBb `T0            {51Testing软件测试网(LO GV0w!{j*i.eH
                psw.AppendChar(c);51Testing软件测试网?#z1WI:~G0p,{mU
            }
5u F"hv%D([/o:L0            processInfo.Password = psw;51Testing软件测试网 daC-acM
            processInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(appPath);
B1X|J-X]| z"J0            pro.StartInfo = processInfo;
r MV8J T.fV8K"jv0            return pro;
)_Fe"k ~$_2Y0        }51Testing软件测试网:tM;sv}&ZuC1G

9T#I VH `${0        /// <summary>51Testing软件测试网6x }w"LC2s
        /// 使用指定帐户绑定进程51Testing软件测试网,XX-j?"KO i-KH
        /// </summary>51Testing软件测试网'uf&^ ];N X/P\
        /// <param name="appPath">进程的宿主程序</param>51Testing软件测试网T \;m^Y3{)C m
        /// <param name="userName">指定本地帐户的用户名</param>
o*aE`PQ0        /// <param name="password">指定帐户的密码</param>
5N&q.R*J IunS!i0        /// <returns>绑定了特定帐户的进程</returns>
jsp4NL%@0        public Process CreateProcessWithUserToken(string appPath, string userName, string password)51Testing软件测试网GXdb(a
        {51Testing软件测试网$r4Lr(Gg"D0u:AI4Q*f
            return CreateProcessWithUserToken(appPath, "", userName, password);51Testing软件测试网(E#q"j$@fU3X
        }51Testing软件测试网XK/{kf }
    }
/P'hFU)\2k2y!G"a0}51Testing软件测试网V1^N2z^9bV S

[l|o5A~#a:K)e0    上面的代码有几个地方需要指出的是:

|voSq!`u051Testing软件测试网%_$QB0\G5p

    1, 应该待运行的程序指定相应的启动路径,否则的话在上述代码运行的过程中可能提示“目录不存在”;51Testing软件测试网|3X5q2j1\~6x

51Testing软件测试网uh'w9W&jPp_

    2,Domain可以不设置,而直接使用bestreme\chdwu的方式给UserName赋值即可;51Testing软件测试网*? [fg6}%\8s

&AtVXW5d'`1z0     3,UseShellExecute 应该设置为False

-G.Vd9o,g7R7S mkd0

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

0l5sq*r,QM051Testing软件测试网!S1Y1J/F!X p:Mcs

结束语51Testing软件测试网n mz4KT2E;CA+a

51Testing软件测试网jw-gk/e4u"vUS"T.K

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

51Testing软件测试网M s:G7J5C0q b'_!vr

     当然实现Run as的代码实现方法很多,在下一篇中将介绍一下有关使用Win32 API的实现。需要指出的是,使用Win32 API几种实现方式存在着一些潜在的问题,详细内容将尽快在下一篇文章中给大家展示。

P QA#I6k,k7c:}0

TAG:

 

评分:0

我来说两句

Open Toolbar