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

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

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

ybW c9V0Q)[01,引入

@Y,b{W051Testing软件测试网 B#v b[/DL

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

6J@s&O$gS5x0Run AS51Testing软件测试网m4OZ~f]QN^

"Y@ a7F;F+I0然后输入一个新的用户帐户,如下图:51Testing软件测试网1G/}GD^&l`R x&V

I|yVZ3nWE!i0 Run As51Testing软件测试网vG*^2z FC

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

N#Z9v f(d`9^z,?C051Testing软件测试网!qV$bk$?g'n

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

e X&i aO3_0~'HO051Testing软件测试网\Uk&{6s+XN#g

Run As51Testing软件测试网k he nO

'J H W.p7]Ezbx3IX0在较近操作系统中,右键菜单中没有了“Run as”,而是变成了“Run As Administrator”,目的是提高运行相应程序的用户权限:51Testing软件测试网E yCpovO"K

GH,ZG8M\!p7H-l0Run AS Admin51Testing软件测试网K)B B#zkOl9V\&u

51Testing软件测试网qGB;f*v}t

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

%LXy;CH#z5cR051Testing软件测试网8V3g'`BW@

2,代码实现命令行Run As

d.W$eaH051Testing软件测试网h"S Z-G,Z9c6L/S

  命令行51Testing软件测试网"F]0{5L Zh.z

51Testing软件测试网&bL!pr7K lX)~0^D

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

NNV9odC _051Testing软件测试网X&]1[$|)n

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

K6V6j)r ounx3G)`6|.\051Testing软件测试网&h2A![.I2wD$k5w

      Python实现

2_!nq i3D5oK.T&z Bf0

4m${z,K*P,@d+d0  RunAsWithinPython.py文件内容如下:

$jcDRE0
Runas Commandline in Python
6d2TNg.Z`Ax0import os51Testing软件测试网"[Br3r&H;J
os.system(
"runas /user:user@domain.com \"C:\Program Files\Internet Explorer\iexplore.exe\"")
2nFG ]$q {+@I0
51Testing软件测试网0Be2^(^4K

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

^$Qdo&rgis0  C#实现 51Testing软件测试网%B v3V%]klb

51Testing软件测试网L2b EC:Jg\

      Program.cs文件内容如下:

c$T'DW4^A/Pl0
Runas Commandline in C#51Testing软件测试网 P+EWUCgJ
using System.Diagnostics;
uI`\ WGE-Ik*N?K0
9K+T+t6K ezc.I9n0
namespace MainTest51Testing软件测试网m'n*~0M9X C
{
x%gE@t2c'\X0J0    
class Program51Testing软件测试网[,C5T%C4vbb0Hwzh
    {        51Testing软件测试网 ?GVV*I
        
public static void Main(string[] args)
5Dt(Q8V @a g0        {
.eLj|;^0            System.Diagnostics.Process cmd 
= System.Diagnostics.Process.Start("runas"
rZ2oTT)Hu:d0                
"/user:user@domain.com  \"C:\\Program Files\\Internet Explorer\\iexplore.exe\"");
iF%a_,x']2^0        }51Testing软件测试网*V;D$iU$]#[
    }
IH MK}0}

b#X%|[Oy y1E7F-U8X h:~0   恩,C#表现也不错,看来确实是一个比较简单的命令而已,如果你没有运行一下这两个程序,你可能以为这样就搞定了,相当简单。但是如果你是一个细心的人,或者你是用过runas命令行的话,你应该知道,这里有问题:51Testing软件测试网*P]:G-O*a C$H4b[JV

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

g.KI6bVDO0

K1SE {V(D"j"x b.w0Runas Helper51Testing软件测试网yx"f-ES,Yg&f

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

$Ue'SLQ'\'B#dX051Testing软件测试网"LIB!X6]/[G

3, 使用Process的ProcessStartInfo实现51Testing软件测试网W8g'|:sRA d\

51Testing软件测试网 WIm^-x2|p

51Testing软件测试网A9Avo5Fx

ProcessUserLogonHelper
:xMd2u&z'mAp0using System;
-\T j8_kSz$m%N$M$X0
using System.Collections.Generic;
#i'|]T?Q^0
using System.Linq;51Testing软件测试网 oJA-Qw'h b-V'k A
using System.Text;51Testing软件测试网"Vfb'{Ir}Q
using System.Diagnostics;51Testing软件测试网"M7k?,C[b
51Testing软件测试网 w'F },OC8^~+t{"A
namespace MainTest
_"q G/a6G+]0{51Testing软件测试网A+z2EJ4L:l\n
    
class ProcessUserLogonHelper
'I @ wk$p_Mv-E0    {
GfZ c AE t8}0        
/// <summary>51Testing软件测试网QA*nmKU
        
/// 在Main函数中调用该方法的的示例代码
1tg1v4|n&rJC,d?/R0        
/// </summary>51Testing软件测试网-s&Z&?/N/@ W
        private void InvokeExample()
Q6Sj np#MJ\+~z0        {51Testing软件测试网wD6g+X4j:b`$]
            ProcessUserLogonHelper phelper 
= new ProcessUserLogonHelper();
U/aHP-PA0Q1L0            Process pro 
= phelper.CreateProcessWithUserToken(@"C:\Program Files\Internet Explorer\iexplore.exe""bestreme.com""chdwu""************");
&RW X/c9Nu0            pro.Start();
D:VM#d#bl3?D3q0        }51Testing软件测试网ncH]*xT` PRy
51Testing软件测试网mZx{1A9}R
        /// <summary>
X\r|4G0        /// 使用指定帐户绑定进程51Testing软件测试网j^*da;| ~$@C
        /// </summary>51Testing软件测试网%G)@J+B^3R|r2]7t KJ
        /// <param name="appPath">进程的宿主程序</param>
LkPj5r[/d0        /// <param name="domain">指定帐户的域名</param>
vd$ey.DKN `I0        /// <param name="userName">指定帐户的用户名</param>
0RlB&f(X0A^+fW1[0        /// <param name="password">指定帐户的密码</param>51Testing软件测试网UZl2V:ZF'`1W
        /// <returns>绑定了特定帐户的进程</returns>51Testing软件测试网X_Dr/n1~^q
        public Process CreateProcessWithUserToken(string appPath,string domain, string userName, string password)51Testing软件测试网_Fh+Rp o!W`4d
        {
e1wt!_|w fw0            Process pro = new Process();
N DhdSs#?$]0            ProcessStartInfo processInfo = new ProcessStartInfo(appPath);51Testing软件测试网2D1S%J1m(B,Z2VC
            processInfo.UseShellExecute = false;
6luE7A:FMK)O0            processInfo.UserName = userName;51Testing软件测试网nc9X3o8|M
            processInfo.Domain = domain;
%C/E!P}!jqG0            System.Security.SecureString psw = new System.Security.SecureString();
C-D@u7k0            foreach (char c in password.ToCharArray())
M9^ p }3`%] j8^"A2H0            {
2N6KP~db0                psw.AppendChar(c);51Testing软件测试网tze1]}uE
            }51Testing软件测试网G1H-s4` d
            processInfo.Password = psw;51Testing软件测试网%f2W%Z6IL-P4\ O
            processInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(appPath);51Testing软件测试网hoC#v\|[+Jd
            pro.StartInfo = processInfo;51Testing软件测试网Z\:n|e'tl @
            return pro;51Testing软件测试网'n6I#Dm-Tp+P,GSrw
        }
0u s"m8`kqH{0
Y ]{ w e0        /// <summary>
5U#O#PT$d0        /// 使用指定帐户绑定进程
#d)vN)~}0        /// </summary>
b ?)E\f2Wm0        /// <param name="appPath">进程的宿主程序</param>51Testing软件测试网/n j(E@ x_
        /// <param name="userName">指定本地帐户的用户名</param>
xnD EO*LEX @a0        /// <param name="password">指定帐户的密码</param>51Testing软件测试网&e[})s:KS|
        /// <returns>绑定了特定帐户的进程</returns>51Testing软件测试网)V,K tHl7p'^
        public Process CreateProcessWithUserToken(string appPath, string userName, string password)
nH-rf&a0        {51Testing软件测试网JR7t8@1jB:W
            return CreateProcessWithUserToken(appPath, "", userName, password);
rI IZ6e4f-Z0        }
{\0nZz-E0    }
T3~D9[K g U0}51Testing软件测试网 [.b5?u"om7f'F*g
51Testing软件测试网H)e%F/GEv8M

    上面的代码有几个地方需要指出的是:

J%ZR6i%B051Testing软件测试网uO yyf/RR${

    1, 应该待运行的程序指定相应的启动路径,否则的话在上述代码运行的过程中可能提示“目录不存在”;51Testing软件测试网2fh&{ g5zs

51Testing软件测试网)Jpu/P i w

    2,Domain可以不设置,而直接使用bestreme\chdwu的方式给UserName赋值即可;51Testing软件测试网v(s1qB,hrz;[&d

51Testing软件测试网-^C/nZInw"j)x

     3,UseShellExecute 应该设置为False

1v;y4?Xz051Testing软件测试网(]0M@q6{\)`)D-fA(w5A&~

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

`X8I U8u'^051Testing软件测试网0juW`f5C]

结束语

t.G`dJ0

z l~.xmU)M0  上面为大家介绍了几种Run as的实现方式,其中的前面两种分别用Python和C#实现了命令行Run as的功能,第三种方法则是在ProcessStartInfo中加入了用户信息以实现用指定用户启动运行应用程序。51Testing软件测试网1V,L? y8J`(~N

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

?+}5KWs-U+k0

TAG:

 

评分:0

我来说两句

Open Toolbar