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

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

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

51Testing软件测试网/{mq"f2r

1,引入51Testing软件测试网@,K_Ubb]

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

0l1Dq\Sdz([N0

wM4I2}/Ag:gF b0Run AS

U#B]DH d0

!B"Q H] e*n5k0然后输入一个新的用户帐户,如下图:

9_7YG2IZ2C051Testing软件测试网Vd3\&M3B b3U

 Run As

+O8H4f"g'}4m051Testing软件测试网 X _HMmr

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

51Testing软件测试网D/AJwzf

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

Px,]#U(De"Yk0

iu.~)PZ0Run As51Testing软件测试网0x4u)n3uB7} HK

51Testing软件测试网'QRQOVPt

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

Z6q;[-k N@\J(af&bh051Testing软件测试网@9@R(|R8yU;Gd+c

Run AS Admin51Testing软件测试网1] @Z+J1a,p&]

6D9fH_|3G0  好了,言归正传,今天笔者提到的则是使用代码来实现相同的功能,即以更改运行程序的用户帐户。

TiC3`"C-i}0

.c1]5Z Cm v2m02,代码实现命令行Run As

*t)S-O7{t:P:F$O051Testing软件测试网8V.[UwG

  命令行51Testing软件测试网VM8g Y]T;Vm[

51Testing软件测试网G3D,~"I%}t(E

     用命令行实现上述的Run as功能大致可以这样写:51Testing软件测试网}-H p X7v-v(])h

51Testing软件测试网,j8AIV3F ^ah+V

      runas /user:user@domain.com "C:\Program Files\Internet Explorer\iexplore.exe"51Testing软件测试网2@,p/Fp;fBG8OBnV

4D G%`7u j;`0      Python实现

VW.L*E4V0

GyXGx@fi0  RunAsWithinPython.py文件内容如下:

c;xxSYP]0
Runas Commandline in Python51Testing软件测试网-J%f[b%iX
import os51Testing软件测试网 ~U1V4V;c+j^
os.system(
"runas /user:user@domain.com \"C:\Program Files\Internet Explorer\iexplore.exe\"")51Testing软件测试网z@9y,Z.V,|$q
51Testing软件测试网S2CBU)`*k iI(M

     额,就这两行,看起来比命令行内容多不了几个字符,不得不惊诧Python的强悍。另外,python使用缩进来表示代码层次而不是我们在C#等语言中用的大括号“{”,代码看起来很爽,当然,这是闲话了。51Testing软件测试网`_*o#t(p*e-n

1a\XW f6i8jh1d/T#V0  C#实现 51Testing软件测试网6rmm$HlVJ8B

51Testing软件测试网b[ ]paG)t

      Program.cs文件内容如下:

RA/SI"U$W&{*jL0
Runas Commandline in C#
0LP9zml0using System.Diagnostics;
E a e9[qle] j'T051Testing软件测试网U5[NpY.l&g
namespace MainTest51Testing软件测试网!c"cNV6[4Q5j;V my6X
{
X;lWB"p0s.fH g$\7]#i0    
class Program51Testing软件测试网iA3l w:d
    {        
}z4S2A xY/A {@0        
public static void Main(string[] args)51Testing软件测试网(?fm'Obm
        {51Testing软件测试网b6tJJP F'^o [
            System.Diagnostics.Process cmd 
= System.Diagnostics.Process.Start("runas"
*@ j?6a u a3s0                
"/user:user@domain.com  \"C:\\Program Files\\Internet Explorer\\iexplore.exe\"");51Testing软件测试网9ztCw(}R
        }51Testing软件测试网$xfO'F]kPD
    }51Testing软件测试网N8V!frPE
}
51Testing软件测试网|z,I#lfr,M?

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

2hJ7onZi`|051Testing软件测试网G7X!J(OC[;U

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

-}Gm}![.{2Q.D3af6w0Runas Helper51Testing软件测试网JNAN7A

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

B^9UEYGD4i!{#UQ7q0

VY"\h"D.a0g03, 使用Process的ProcessStartInfo实现51Testing软件测试网oI4W4}gt.aL,_@

51Testing软件测试网&?.L6Bus LT:j

x&U:h)T+QM0
ProcessUserLogonHelper
$?W$SdYku*N)[K-u0using System;51Testing软件测试网9^ Gni"L,h yU \3LI
using System.Collections.Generic;
#n.m2Q$]5n0
using System.Linq;
'l9t0VG ~s%l0
using System.Text;
0Pf4f'KBG8{0
using System.Diagnostics;
+Ml,[_2F{+y5t1[0
'~p&guE4A _0
namespace MainTest51Testing软件测试网P,@ Zc&rJ
{51Testing软件测试网$Ze;[J6|\ hcK
    
class ProcessUserLogonHelper51Testing软件测试网o!sS4Q0fF!T6~
    {51Testing软件测试网%s PoP|6N0tVa$~$j
        
/// <summary>51Testing软件测试网1?'Ta$IbLC!z { B1D
        
/// 在Main函数中调用该方法的的示例代码51Testing软件测试网t+V(~vB"z%Qd`
        
/// </summary>
cK z&]$|vTxR0
        private void InvokeExample()51Testing软件测试网e,hP Fk3l
        {
1|&jZ'u%x(Y0            ProcessUserLogonHelper phelper 
= new ProcessUserLogonHelper();51Testing软件测试网gB[/F5SJ:}^$P
            Process pro 
= phelper.CreateProcessWithUserToken(@"C:\Program Files\Internet Explorer\iexplore.exe""bestreme.com""chdwu""************");
p)v @:s-K;Zwy;i0            pro.Start();51Testing软件测试网:wE8F4J!y_&r R6W
        }51Testing软件测试网,]+kn*o(@s)_
51Testing软件测试网6^6^s:q9r ? ^0^
        /// <summary>
{L'y d }H0        /// 使用指定帐户绑定进程
9xYx5m]j7n0        /// </summary>
w0~-Z%JKg-q0        /// <param name="appPath">进程的宿主程序</param>
?H(R1t M0        /// <param name="domain">指定帐户的域名</param>
)v6T,}yS0~0        /// <param name="userName">指定帐户的用户名</param>51Testing软件测试网1U0H^5j9e bZ/K-C
        /// <param name="password">指定帐户的密码</param>51Testing软件测试网4y0btr;] u(|c ?
        /// <returns>绑定了特定帐户的进程</returns>51Testing软件测试网-q%^&T;TSt-l+G
        public Process CreateProcessWithUserToken(string appPath,string domain, string userName, string password)
r4mxZqGvQ0        {51Testing软件测试网9TXT&\ p }E
            Process pro = new Process();51Testing软件测试网6J2?Ps*b?z9t$Cp
            ProcessStartInfo processInfo = new ProcessStartInfo(appPath);51Testing软件测试网:l Y3U4u$`E
            processInfo.UseShellExecute = false;51Testing软件测试网3RT-Pr:p7C-Q
            processInfo.UserName = userName;51Testing软件测试网.T AQP_#TE
            processInfo.Domain = domain;51Testing软件测试网6D p7t}+AX"Rcg
            System.Security.SecureString psw = new System.Security.SecureString();51Testing软件测试网&yG] do!g+z
            foreach (char c in password.ToCharArray())51Testing软件测试网9x+PZ,sC+b&j@#y
            {51Testing软件测试网1l@uk5K5e"R-[,]"K{
                psw.AppendChar(c);
g:CZGz0            }
8A.|:h2M-@~$L.a8EGNb0            processInfo.Password = psw;
%DVX7nQ;t0            processInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(appPath);51Testing软件测试网3Xf R9Y5j.Z
            pro.StartInfo = processInfo;
F&M@:c'T}0            return pro;
a:F$T:T]m0        }51Testing软件测试网fUUV@KD7k5kY
51Testing软件测试网He&T'f-PLJ?5i
        /// <summary>
6iX{^)V)D0        /// 使用指定帐户绑定进程51Testing软件测试网w{_j#m:{
        /// </summary>
;f`,i?.Ep7A0        /// <param name="appPath">进程的宿主程序</param>51Testing软件测试网!n;z*L7D"xD
        /// <param name="userName">指定本地帐户的用户名</param>51Testing软件测试网X1kzZ wG5\n+@
        /// <param name="password">指定帐户的密码</param>51Testing软件测试网xa(UF A@8EC
        /// <returns>绑定了特定帐户的进程</returns>51Testing软件测试网{I|u@1nj*_2r
        public Process CreateProcessWithUserToken(string appPath, string userName, string password)
&{#l/F!s$G;x4M0oJo0        {
*Z L*DP^W${0            return CreateProcessWithUserToken(appPath, "", userName, password);51Testing软件测试网Wcb3t2AI
        }51Testing软件测试网L5bW(f^ I
    }
hj.p9zvsji+[!L/x })y0}51Testing软件测试网`YKx6Is`7F
51Testing软件测试网X0TF'~ Y-o

    上面的代码有几个地方需要指出的是:51Testing软件测试网I-fx3L7E"y'xJ

51Testing软件测试网a/H4G#s6\

    1, 应该待运行的程序指定相应的启动路径,否则的话在上述代码运行的过程中可能提示“目录不存在”;51Testing软件测试网'rq{6B ew'f:G

51Testing软件测试网jzy~){aR_G}

    2,Domain可以不设置,而直接使用bestreme\chdwu的方式给UserName赋值即可;

J)n9b;C*\ ZQA/L051Testing软件测试网8~.y!v-Z["A$N

     3,UseShellExecute 应该设置为False51Testing软件测试网5e ~5[G2c#mZ'^Hs

GX9t@7nm#F&j?3b0     4,ProcessStartInfo中的password是System.Security.SecureString类型的,所以如果我们只是传入了一个string作为password,我们应该将其转换为正确的类型。51Testing软件测试网D$jV fg-Y

-lu9^"WcK M/`0lAn0结束语

k8?'m;[ a4P8Qr6e.nD051Testing软件测试网#lNlM5i#X

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

bQ{2jk2m[7|nW0

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

E o%f2G z+}0

TAG:

 

评分:0

我来说两句

Open Toolbar