发布新日志

  • 【转 】shell计算明天和昨天日期的函数

    2010-10-19 14:59:34

    #返回月份的天数
    get_mon_days()
    {
    Y=`expr substr $1 1 4`
    M=`expr substr $1 5 2`

    r1=`expr $Y \% 4`
    r2=`expr $Y \% 100`
    r3=`expr $Y \% 400`

    case $M in
    01|03|05|07|08|10|12) days=31;;
    04|06|09|11) days=30;;
    esac
    if [ $M -eq 02 ]
    then
    if [ r1 -eq 0 -a r2 -ne 0 -o r3 -eq 0 ]
    then
    days=29
    else
    days=28
    fi
    fi
    echo $days
    }
    #返回昨天日期
    get_before_date()
    {
    Y=`expr substr $1 1 4`
    M=`expr substr $1 5 2`
    D=`expr substr $1 7 2`
    YY=`expr $Y - 1`
    MM=`expr $M - 1`
    DD=`expr $D - 1`
    MM=`printf "%02d" $MM`
    DD=`printf "%02d" $DD`
    dd=$Y$MM
    dad=`get_mon_days $dd`
    be_date=$Y$M$DD
    if [ $D -eq 01 ]
    then
    if [ $M -ne 01 ]
    then
    be_date=$Y$MM$dad
    fi
    if [ $M -eq 01 ]
    then
    be_date=$YY"1231"
    fi
    fi
    echo $be_date

    }
    #返回明天日期
    get_next_date()
    {
    Y=`expr substr $1 1 4`
    M=`expr substr $1 5 2`
    D=`expr substr $1 7 2`
    YY=`expr $Y + 1`
    MM=`expr $M + 1`
    DD=`expr $D + 1`
    MM=`printf "%02d" $MM`
    DD=`printf "%02d" $DD`
    r1=`expr $Y \% 4`
    r2=`expr $Y \% 100`
    r3=`expr $Y \% 400`

    next_date=$Y$M$DD

    if [ $D -eq 30 ]
    then
    case $M in
    04|06|09|11) next_date=$Y$MM"01";;
    esac
    fi
    if [ $D -eq 31 ]
    then
    next_date=$Y$MM"01"
    case $M in
    12) next_date=$YY"0101";;
    esac
    fi
    if [ $M -eq 02 ]
    then
    if [ r1 -eq 0 -a r2 -ne 0 -o r3 -eq 0 ]
    then
    if [ $D -eq 29 ]
    then
    next_date=$Y$MM"01"
    fi
    else
    if [ $D -eq 28 ]
    then
    next_date=$Y$MM"01"
    fi
    fi
    fi
    echo $next_date
    }


  • shell 运算和进制转换

    2010-10-19 14:56:57

    【转 】shell 运算和进制转换

    Shell 提供大量的基本运算操作,在脚本中非常有用。Shell 对您提供的算术表达式求值,执行运算展开式,此时使用得出的结果替换表达式。以下面的格式提供运算表达式:

    $(( expression ))

                           


    您可以使用 echo 在命令行显示运算展开式的结果,了解其工作情况。现在尝试清单 5 所显示的结果。

    清单 5. Bourne Shell 中的运算展开式

                        

                            $ echo $((10+40))

                            50

                            $ echo $((5*(3+3)))

                            30

                           


    您还可以将展开式分配给变量。尝试清单 6 所显示的结果。

    清单 6. 将运算展开式分配给 Shell 变量

                        

                            $ myvar = 10

                            $ echo $myvar

                            10

                            $ echo $(($myvar-2))

                            8

                            $ myvar = $(($myvar+5))

                            $ echo $myvar

                            15

                            $ result = $(($myvar-10))

                            $ echo $result

                            5

                            $

                           


    表 2 列出了在大多数 Bourne 以及与 Bourne 兼容的 Shell中可以使用的运算符。正如上面第二个示例,使用圆括号括起来的语句有更高的优先级。实际上,Shell 算术优先级通常根据 C 语言的规则来确定。

    表 2. Shell 条件表达式
    运算符     描述
    +     加
    -     减
    *     乘
    /     除
    %     求余
    <     小于(1 代表真,0 代表假)
    <=     小于等于(1 代表真,0 代表假)
    >     大于(1 代表真,0 代表假)
    >=     大于等于(1 代表真,0 代表假)
    <<     按位向左移位:将给定的整数或第一个表达式向左移动第二个表达式表示的位数
    >>     按位向右移位:将给定的整数或第一个表达式向右移动第二个表达式表示的位数


    使用 Shell 运算进行进制转换

    假 定在您的脚本中有一些数字,您需要以另外的进制处理这些数字。使用 Shell 运算可以很容易地自动实现这类转换。一种情况是使用 Shell 运算把一个数字从给定的进制转换位十进制。如果数字以运算展开式的形式提供,那么假定它带有十进制符号,除非 它前面带有 0(这种情况假定是八进制)或 0x(这种情况假定是十六进制)。键入以下内容以得到一些八进制和十六进制值的十进制输出:

    $ echo $((013))

     $ echo $((0xA4))

                                           
    您还可以使用以下格式指定 2 到 64 之间的任意进制:

    $((BASE#NUMBER))                 
    通过在 Shell 提示符后键入清单 7 中所示的行,尝试将二进制、八进制、十六进制以及其他进制的数转换为十进制。

    清单 7. 在 Shell 中将任意进制的数以十进制输出
                      

                            echo $((2#1101010))

                            echo $((8#377))

                            echo $((16#D8))

                            echo $((12#10))

                            echo $((36#ZZYY))

                           


    使用 bc 进行进制转换

    在 Shell 中进行进制转换的另一个诀窍是使用 bc, 它是一种任意精度运算语言,大多数 UNIX 安装程序都提供。因为它允许您指定输出进制,所以当您需要以十进制以外的进制输出时,这是一种很好的技术。

    bc 的特殊变量 ibase 和 obase 分别包含用于输入和输出的进制的值。缺省情况下,都被设置为 10。要执行进制转换,需要改变其中的一个或两个值,然后提供一个数字。立即尝试,如清单 8 中所示。

    清单 8. 使用 bc 执行进制转换

                        
                            $ bc -ql

                                                10

                            10

                            base=16

                                                10

                            A

                            ibase=2

                                                10

                            2

                           

                                                     Control-D

                                               

                            $

                           
    要快速执行进制转换,可以联合使用 bc 和 echo形成快捷的单命令行程序,将给定的值通过管道传输给 bc。键入清单 9 中显示的内容。

    清单 9. Shell 单命令行 bc 程序

                        

                            $ echo 'obase=16; 47' | bc

                            2F

                            $ echo 'obase=10; ibase=16; A03' | bc

                            2563

                            $

                           


    警告:当您设置 bc 的输入进制以后,输入 bc 的所有数字都使用该进制,包括您提供用于设置输出进制的数字。因此最好先设置输出进制,否则可能会产生意想不到的结果,如清单 10 中所示。

    清单 10. 设置输入和输出进制的先后顺序的重要性

                        

                            $ echo 'ibase=16; base=10; A' | bc

                            A

                            $ echo 'ibase=16; base=A; A' | bc

                            10

                            $

                           

    运 算符类型
    按位运算符
    ~, <<, >>, &, |, ^
    $[]表示形式告诉 shell 对方括号中的表达式求值
    shell运算符
    表达式替换
    $[ ] 和 $(())
    两种格式功能一样,所有的 shell 的求值都是用整数完成
    $[ ] 可以接受不同基数的数字
    shell运算符
    赋值运算符
    =、+=、-=、*=、/=、%=、&=、^=、|=、<<=、>>=

  • QTP之右键录制.

    2009-10-21 16:45:01

     

    例如作这样一个录制(鼠标右击开始菜单,选取属性)
      使用Wscript.Shell的方法如何录制:

    Window("Window").WinButton("开始").Click 0, 0, micRightBtn    '选择对象
      Dim Wsh,n                                        '定义参数,其中N向上向下移动的次数.
      n=7 '对应循环的次数
      Set Wsh=CreateObject("Wscript.Shell")
      For i=1 to n
      wait 1                                       '等待一秒可以清楚地看到效果
     Wsh.SendKeys "{UP}"              ' 相当于鼠标向上移动三次DOWN为向下.


      Next
      Wsh.SendKeys "{Enter}"          '按下回车键选取属性
      Set Wsh=nothing '释放Wsh变量

    附: wsh键值表
    键          参数
    退格键      {BACKSPACE}、{BS}或{BKSP}
    BREAK       {BREAK}
    CAPS LOCK   {CAPSLOCK}
    DEL或DELETE{DELETE}或{DEL}
    下箭头      {DOWN}
    END         {END}
    ENTER       {ENTER}或~
    ESC         {ESC}
    HOME        {HOME}
    INS或INSERT{INSERT}或{INS}
    左箭头      {LEFT}
    NUM LOCK    {NUMLOCK}
    PAGE DOWN   {PGDN}
    PAGE UP     {PGUP}
    PRINT SCREEN{PRTSC}
    右箭头      {RIGHT}
    SCROLL LOCK{SCROLLLOCK}
    TAB         {TAB}
    上箭头      {UP}
    F1、F2、F3...{F1}、{F2}、{F3}Q

  • 转贴“vista和xp双系统安装”下次不用到处找了

    2009-08-12 14:34:06

    第一、安装方法



    一. 保留c盘vista和一键还原功能, 在其他盘安装xp的方法
    1. 网上下载两个软件:
    1). Microsoft.NET 2.0 Framework或以上版本,
    推荐下载地址:
    http://down1.tech.sina.com.cn/download/downContent/2006-01-16/16911.shtml
    http://dl.pconline.com.cn/html_2/1/82/id=10637&pn=0.html
    2).VistaBootPRO3.1或以上版本(最好是3.2版)
    推荐下载地址:
    http://www.jrcons.net/pronet/VistaBootPRO_3.2.0.exe
    http://www.area59.org/vistabootpro/dl/VistaBootPRO_3.2.0.exe
    2 用xp安装盘安装xp系统到D/E/F/G中任一个没有数据的硬盘分区.
    3. 完成后会发现系统直接进入xp系统, 此时安装Windows.NET 2.0 Framework, 然后安装VistaBootPRO3.2(3.2与3.1界面有不同之处)
    4. 管理员身份运行(鼠标移到vistabootpro图标,单击右键,选择),输入密码.(当然如果你的电脑上因为某种原因无法以管理员身份运行,直接双击打开也是可以的). 打开vistabootpro这个软件后, 提示备份(英文), 点确定.  
    进入"BCD Registry Backup/Restore Center".  这个界面很重要, 因为稍后我们做完的操作将会改写系统启动时的菜单, 最后应该在这里把设置保存下来, 以后恢复双系统时有用. 
    **上面BCD backup path是让你选择一个保存bcd数据的地址. 点右边Browse, 选择一个非系统硬盘分区保存文件. 文件名可以随便写.**
    要记住这个位置. 因为以后重装系统要用到下面一项
    BCD Restore Path (恢复路径)
    点open, 然后找到上面保存的那个文件, 双击打开就可以完成bcd数据恢复. 自动完成启动时的双系统选择菜单了.
    5. 注意file tools diagonstics help 顶行菜单下面还有一行矩形菜单,
    刚才我们进行的是在第四个项目"backup/restore center". 第一个是viewsettings, 点击viewsettings, 你就会看到所有操作系统的启动信息. 看看里面有几个. 如果只有xp, 那么就点第二个"manage OS Entries", 最下面"add new OS entry"勾上. os name写vista, type: vista, OS Drive选择vista实际安装的分区. 完成以后点最下角的Apply Updates. 可能会提示有错误, 不用管, 一律确定到底. 弹出的记录窗口全部关闭. 然后你也可以再在此菜单下选择修改操作系统的名称, 如把"早期windows操作系统"改成xp (注: 这里好像不支持中文). 选上set as default表示启动时默认选择的操作系统. current boot timeout里面可以调节操作系统自动进入前的等待时间. 后面两条也可以到vista操作系统里面修改.最后别忘了还是要点击'apply update"
    6 倒数第二个菜单: systembootloader是最关键的步骤. 选择windows vista bootloader和 system partition就可以了. 点最下角install bootloader. 重启应该可以看到双系统选择菜单了. 
    (如果还是不行,你可以补充操作别的论坛里面提到的一个步骤:
    "进入C盘根目录,打开文件夹选项的查看,将隐藏受保护的操作系统文件的勾去掉,并选择显示隐藏的文件和文件夹。
    这时你能看到ntldr这个文件了,打开ntldr这个文件的属性,把它的只读属性去掉。")
    注: vistabootpro3.1的用法可以参考
    http://bbs.123z.cn/viewthread.php?tid=12318
     有图
    7. 回到xp, 重新打开vistabootpro, 操作步骤4里面提到的**...**中间部分. 以后重装双系统直接用bcd restore path就可以了.
    8. 有部分vista装机时就装好的软件如easycapture, powergo等在随机赠送的软件大礼包光盘里. 安装一下.


    二  先装xp再装vista的方法
    1. 用xp安装盘安装xp到c盘, 如果本来c盘已经安装了xp就不用了.
    2. 进入xp, 把vista安装盘放入光驱, 然后打开光盘的目录, 选择setup.exe, 双击就可以开始安装了. 首先会提示你输入密钥. 在笔记本的底部找. 如果你用的是盗版光盘或者你自己知道密钥在哪儿就随便拉.
    然后按照提示选择重新安装(不要选择升级安装)在c盘以外的任何一个分区(要求是ntfs格式.可以自己在xp的管理中先格式化该分区成ntfs格式)就可以了.
    注: 刚才用的是像安装普通软件一样的硬件安装法.请不要尝试dos里面或者win PE或者光盘启动系统法来安装vista, 因为这样安装完成后, vista会把所在盘符自动改成C盘, 这样和xp系统的盘符就不一致了.)
    3.安装过程中电脑会自动重启若干次. 完成以后的启动画面里会自动有双系统选择菜单
    4. 装好以后安装驱动程序; 
       vista手动装到非c盘的分区后, 设备管理器上有4个问号. 头3个都可以通过把随机驱动程序光盘放到光驱, 用搜索光驱所在盘的方法解决. vista在这面比xp有了明显的进步, 就是它可以让你在搜索驱动文件的时候选择该文件所在的盘符, 然后加选子文件夹. 这意味着你的驱动程序文件放到光盘或者硬盘上都一样方便. 
    还剩一个未知设备. 经过摸索, 和装xp时一样, 要把电源管理软件装上. 只是, 装xp时驱动程序文件夹选f50pm. vista选择engergycut这个文件夹, 打开点setup装好以后就没有问号了.
    不过还有几个步骤要做:
    a. 虽然vista装好就有声音和视频功能,  你仍然需要手动安装2.audio文件夹里的setup文件. 重启后就可以看到任务栏多了一个红色的小喇叭了. 里面可以管理扬声器, mic, 混音还有音效. 注意: 装上这个声卡驱动管理文件以后, 你无法在聊天室唱歌的同时用混音.xp里面的可以. 这是一个很多购买了realtek HD声卡的新笔记本的通病, 网上很多人在发牢骚. 联想华硕的技术部门会告诉你此问题纯属硬件问题无法通过升级驱动程序或者第三方软件解决. 我升级过最新的(4月26日左右)的realtek HD的vista驱动, 的确没用. 如果你一定要在vista里面也要用混音的话,只有一款驱动程序可以凑合使用, realtek HD驱动的1.42版 --这一发现几乎花去了我10个钟头的尝试.
    b 装好软件包里的easy capture, 再重启, 摄像头就可以用了.
    . easybutton驱动我也重装了.
    这就算成功了.
    不过呢,以后xp每次重装, 都可能会导致vista选项丢失或者启动时出现winload.exe丢失的问题. 所以, 你还是要在xp里面像上面"一"中讲得那样安装vistabootpro软件才好. 除非你懂得如何运用命令bcdedit.exe来修改启动信息. 这一点可是按今天早上才明白的道理啊. 稍后再详述, 先补充一个技巧:
    关于如何释放一键还原所在的隐藏分区:
    仅适合现在流行的EISA隐藏分区, 即你可以在xp或者vista的'我的电脑"右键选择管理,磁盘管理, 中看到有一个没有盘符的分区, 属性是EISA, 不是FAT也不是ntfs. 当然其本质是隐藏着的FAT格式分区. 如果你的电脑上已经有很多文件就不要删了. 因为下面的技术需要一定的电脑功底(当然俺都是第一次自学成功的.) 
      1) 从XP安装盘启动后,直接在安装界面将这个分区删除了. 方法选择最后那个分区(没有盘符的那个, 大小和磁盘管理里看到的一样), 按D.
      2) 重启后进入磁盘管理, EISA分区消失, 在下面磁盘图形表中发现多出一个11.91G的黑色的"未分配"区. 注意这个未分配区如果直接建立新的分区,不是逻辑分区而是主区. 所以会引起很多麻烦. 找一个Norton Partiion Magic分区软件, 首先删除它, 然后把它和其他的分区合并再重新分区.


    二、备份方法


    三. xp-vista或者vista-xp双系统备份方法:
    先来学习一段网上的引文
    "Windows Vista 引入了Boot Manager的概念和BCD的概念. 
    POST (系统自检)->BIOS读取MBR->找到硬盘分区表中Active的分区->读取Boot Sector-> 加载BOOTMGR (Boot Manager). Boot Manager 读取BCD信息然后列出启动菜单
    -如果Windows Vista 被选中的话. BOOTMGR将控制权交给Winload.exe 然后启动系统. 并开始核心加载
    -如果是XP/2000/2003被选中的话, BOOTMGR将控制权交给NTLDR, 然后开始普通的Windows 加载."
    引自: http://softbbs.pconline.com.cn/topic.jsp?tid=6429289&topicPage=103
    装完vista-xp或者xp-vista双系统后, 备份系统可以在系统出现大故障时迅速恢复系统, 而避免烦琐的重新安装xp和vista以及驱动程序, 还有随后的一些软件设置.
    Norton ghost是最常用的系统备份软件. 我以前一直用来备份我的98-xp双系统. 每次只要10多分钟就恢复到我备份的一个C盘状态.
    备份xp和vista双系统的常见问题.
    1. 在保留一键还原的vista-xp双系统里, c盘不能出现格式改变或者空间大小变化.否则一键还原会失效, 提示winload.exe丢失或者c盘已经改变无法进入一键还原操作. 即使用ghost自行备份的gho文件也不能恢复成功. 
    2. 即使vista所在盘没有变过格式或大小, 有人ghost8.3版本以后的ghost备份vista系统可以直接还原成功. 但是更多的人还原后无法启动, 提示winload.exe. 网上有人给出一个补救办法:
    "可以在製作ghost文件之前在vista系統裡面以administrator權限咝幸韵旅睿�
    BCDEDIT /set {bootmgr} device boot
    BCDEDIT /set {default} device boot
    BCDEDIT /set {default} osdevice boot
    然後再對系統ghost,這樣製作的ghost文件就不會有錯誤了,
    對於已經用ghost恢復後不能啟動的系統也可以用以下辦法恢復:
    用windows PE 光盤啟動,在命令行下cd c:windowssystem32,然後咝幸陨先忻睿貑⒓纯蛇M入系統。"
    引自http://www.mobile01.com/topicdetail.php?f=174&t=289137
    但是这个方法好像是针对vista正式版本以前的版本而设立的. 我尝试过, 头两个命令有效, 第三个无法执行.
    3. 我本来以为这个问题是先装vista后装xp才有的, 于是我把系统改成了xp-vista系统. c盘先装xp, G盘后装vista. 这样一来启动菜单就不用设计了. 而且xp可以直接用ghost8.3备份, 可以完全恢复没有问题. vista呢,我找到了最新的norton ghost v12版本, 备份模式和8.3不一样, 功能更强大, 而且支持在vista里面安装. 试了一下恢复G盘, 重启动, 双系统引导系统还在. vista进入正常, 大喜. 昨天晚上xp系统有点小故障, 于是用ghost8.3恢复了c盘, 重启, 糟了, vista进不了了, 提示winload.exe丢失. 郁闷. 弄了半夜才睡觉还是不行.其实所有提示winload.exe丢失并不是真的winload.exe文件丢失了, 主要是开机后进入系统前的引导系统被破坏了. 用ghost备份文件恢复c盘后不就是相当于装好了vista又装了一遍xp么? 办法当然是在到vista里面用vistabootpro设置一下罗. 于是拒绝重装vista, 直接到xp里装好vistabootpro, 如前面提到过的设置, 重启, 成功. 于是认识到:
    vista和xp双系统的备份最方便的办法是, 在备份前xp里装好vistabootpro, 每次恢复xp系统后, 如果碰到问题, 重新设置一下vistabootpro就好了. 备份所用的软件推荐ghost v12 (可惜目前只有英文版的, 另外还需要在网上下载一个ghost recovery disk的镜像文件刻成光盘, 在xp和vista都进不去时用于启动电脑来恢复系统.因为ghost v12不支持dos环境. )

  • 详细dos命令

    2009-07-17 16:16:54

    1 echo 和 @
    回显命令
    @         #关闭单行回显
    echo off      #从下一行开始关闭回显
    @echo off      #从本行开始关闭回显。一般批处理第一行都是这个
    echo on       #从下一行开始打开回显
    echo        #显示当前是 echo off 状态还是 echo on 状态
    echo.       #输出一个”回车换行”,空白行
              #(同echo, echo; echo+ echo[ echo] echo/ echo)

    2 errorlevel
    echo %errorlevel%
    每个命令运行结束,可以用这个命令行格式查看返回码
    默认值为0,一般命令执行出错会设 errorlevel 为1

    3 dir
    显示文件夹内容
    dir        #显示当前目录中的文件和子目录
    dir /a       #显示当前目录中的文件和子目录,包括隐藏文件和系统文件
    dir c: /a:d     #显示 C 盘当前目录中的目录
    dir c: /a:-d     #显示 C 盘根目录中的文件
    dir c: /b/p     #/b只显示文件名,/p分页显示
    dir *.exe /s     #显示当前目录和子目录里所有的.exe文件

    4 cd
    切换目录
    cd        #进入根目录
    cd        #显示当前目录
    cd /d d:sdk     #可以同时更改盘符和目录

    5 md
    创建目录
    md d:abc     #如果 d:a 不存在,将会自动创建中级目录
    #如果命令扩展名被停用,则需要键入 mkdir abc。

    6 rd
    删除目录
    rd abc       #删除当前目录里的 abc 子目录,要求为空目录
    rd /s/q d:temp    #删除 d:temp 文件夹及其子文件夹和文件,/q安静模式

    7 del
    删除文件
    del d:test.txt    #删除指定文件,不能是隐藏、系统、只读文件
    del /q/a/f d:temp*.*
    删除 d:temp 文件夹里面的所有文件,包括隐藏、只读、系统文件,不包括子目录
    del /q/a/f/s d:temp*.*
    删除 d:temp 及子文件夹里面的所有文件,包括隐藏、只读、系统文件,不包括子目录

    8 ren
    重命名命令
    ren d:temp tmp    #支持对文件夹的重命名

    9 cls
    清屏

    10 type
    显示文件内容
    type c:boot.ini   #显示指定文件的内容,程序文件一般会显示乱码
    type *.txt     #显示当前目录里所有.txt文件的内容

    11 copy
    拷贝文件
    copy c:test.txt d:test.bak
    复制 c:test.txt 文件到 d: ,并重命名为 test.bak
    copy con test.txt
    从屏幕上等待输入,按 Ctrl+Z 结束输入,输入内容存为test.txt文件
    con代表屏幕,prn代表打印机,nul代表空设备
    copy 1.txt + 2.txt 3.txt
    合并 1.txt 和 2.txt 的内容,保存为 3.txt 文件
    如果不指定 3.txt ,则保存到 1.txt
    copy test.txt +
    复制文件到自己,实际上是修改了文件日期

    12 title
    设置cmd窗口的标题
    title 新标题     #可以看到cmd窗口的标题栏变了

    13 ver
    显示系统版本

    14 label 和 vol
    设置卷标
    vol        #显示卷标
    label       #显示卷标,同时提示输入新卷标
    label c:system    #设置C盘的卷标为 system

    15 pause
    暂停命令

    16 rem 和 ::
    注释命令
    注释行不执行操作

    17 date 和 time
    日期和时间
    date     #显示当前日期,并提示输入新日期,按"回车"略过输入
    date/t     #只显示当前日期,不提示输入新日期
    time     #显示当前时间,并提示输入新时间,按"回车"略过输入
    time/t     #只显示当前时间,不提示输入新时间

    18 goto 和 :
    跳转命令
    :label     #行首为:表示该行是标签行,标签行不执行操作
    goto label   #跳转到指定的标签那一行

    19 find (外部命令)
    查找命令
    find "abc" c:test.txt
    在 c:test.txt 文件里查找含 abc 字符串的行
    如果找不到,将设 errorlevel 返回码为1
    find /i “abc” c:test.txt
    查找含 abc 的行,忽略大小写
    find /c "abc" c:test.txt
    显示含 abc 的行的行数

    20 more (外部命令)
    逐屏显示
    more c:test.txt   #逐屏显示 c:test.txt 的文件内容

    21 tree
    显示目录结构
    tree d:      #显示D盘的文件目录结构

    22 &
    顺序执行多条命令,而不管命令是否执行成功

    23 &&
    顺序执行多条命令,当碰到执行出错的命令后将不执行后面的命令
    find "ok" c:test.txt && echo 成功
    如果找到了"ok"字样,就显示"成功",找不到就不显示

    24 ||
    顺序执行多条命令,当碰到执行正确的命令后将不执行后面的命令
    find "ok" c:test.txt || echo 不成功
    如果找不到"ok"字样,就显示"不成功",找到了就不显示

    25 |
    管道命令
    dir *.* /s/a | find /c ".exe"
    管道命令表示先执行 dir 命令,对其输出的结果执行后面的 find 命令
    该命令行结果:输出当前文件夹及所有子文件夹里的.exe文件的个数
    type c:test.txt|more
    这个和 more c:test.txt 的效果是一样的

    26 > 和 >>
    输出重定向命令
    > 清除文件中原有的内容后再写入
    >> 追加内容到文件末尾,而不会清除原有的内容
    主要将本来显示在屏幕上的内容输出到指定文件中
    指定文件如果不存在,则自动生成该文件
    type c:test.txt >prn
    屏幕上不显示文件内容,转向输出到打印机
    echo hello world>con
    在屏幕上显示hello world,实际上所有输出都是默认 >con 的
    copy c:test.txt f: >nul
    拷贝文件,并且不显示"文件复制成功"的提示信息,但如果f盘不存在,还是会显示出错信息
    copy c:test.txt f: >nul 2>nul
    不显示”文件复制成功”的提示信息,并且f盘不存在的话,也不显示错误提示信息
    echo ^^W ^> ^W>c:test.txt
    生成的文件内容为 ^W > W
    ^ 和 > 是控制命令,要把它们输出到文件,必须在前面加个 ^ 符号

    27 <
    从文件中获得输入信息,而不是从屏幕上
    一般用于 date time label 等需要等待输入的命令
    @echo off
    echo 2005-05-01>temp.txt
    date <temp.txt
    del temp.txt
    这样就可以不等待输入直接修改当前日期

    28 %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %*
    命令行传递给批处理的参数
    %0 批处理文件本身
    %1 第一个参数
    %9 第九个参数
    %* 从第一个参数开始的所有参数

    批参数(%n)的替代已被增强。您可以使用以下语法:

       %~1     - 删除引号("),扩充 %1
       %~f1     - 将 %1 扩充到一个完全合格的路径名
       %~d1     - 仅将 %1 扩充到一个驱动器号
       %~p1     - 仅将 %1 扩充到一个路径
       %~n1     - 仅将 %1 扩充到一个文件名
       %~x1     - 仅将 %1 扩充到一个文件扩展名
       %~s1     - 扩充的路径指含有短名
       %~a1     - 将 %1 扩充到文件属性
       %~t1     - 将 %1 扩充到文件的日期/时间
       %~z1     - 将 %1 扩充到文件的大小
       %~$PATH : 1 - 查找列在 PATH 环境变量的目录,并将 %1
            扩充到找到的第一个完全合格的名称。如果环境
            变量名未被定义,或者没有找到文件,此组合键会
            扩充到空字符串

    可以组合修定符来取得多重结果:

       %~dp1    - 只将 %1 扩展到驱动器号和路径
       %~nx1    - 只将 %1 扩展到文件名和扩展名
       %~dp$PATH:1 - 在列在 PATH 环境变量中的目录里查找 %1,
            并扩展到找到的第一个文件的驱动器号和路径。
       %~ftza1    - 将 %1 扩展到类似 DIR 的输出行。
    可以参照 call/? 或 for/? 看出每个参数的含意
    echo load "%%1" "%%2">c:test.txt
    生成的文件内容为 load "%1" "%2"
    批处理文件里,用这个格式把命令行参数输出到文件

    29 if
    判断命令
    if "%1"=="/a" echo 第一个参数是/a
    if /i "%1" equ "/a" echo 第一个参数是/a
    /i 表示不区分大小写,equ 和 == 是一样的,其它运算符参见 if/?
    if exist c:test.bat echo 存在c:test.bat文件
    if not exist c:windows (
       echo 不存在c:windows文件夹
       )
    if exist c:test.bat (
       echo 存在c:test.bat
       ) else (
       echo 不存在c:test.bat
       )

    30 setlocal 和 endlocal
    设置”命令扩展名”和”延缓环境变量扩充”
    SETLOCAL ENABLEEXTENSIONS      #启用"命令扩展名"
    SETLOCAL DISABLEEXTENSIONS      #停用"命令扩展名"
    SETLOCAL ENABLEDELAYEDEXPANSION    #启用"延缓环境变量扩充"
    SETLOCAL DISABLEDELAYEDEXPANSION    #停用"延缓环境变量扩充"
    ENDLOCAL            #恢复到使用SETLOCAL语句以前的状态
    “命令扩展名”默认为启用
    “延缓环境变量扩充”默认为停用
    批处理结束系统会自动恢复默认值
    可以修改注册表以禁用"命令扩展名",详见 cmd /? 。所以用到"命令扩展名"的程
    序,建议在开头和结尾加上 SETLOCAL ENABLEEXTENSIONS 和 ENDLOCAL 语句,以确
    保程序能在其它系统上正确运行
    "延缓环境变量扩充"主要用于 if 和 for 的符合语句,在 set 的说明里有其实用例程

    31 set
    设置变量
    引用变量可在变量名前后加 % ,即 %变量名%
    set         #显示目前所有可用的变量,包括系统变量和自定义的变量
    echo %SystemDrive%    #显示系统盘盘符。系统变量可以直接引用
    set p        #显示所有以p开头的变量,要是一个也没有就设errorlevel=1
    set p=aa1bb1aa2bb2    #设置变量p,并赋值为 = 后面的字符串,即aa1bb1aa2bb2
    echo %p%       #显示变量p代表的字符串,即aa1bb1aa2bb2
    echo %p:~6%      #显示变量p中第6个字符以后的所有字符,即aa2bb2
    echo %p:~6,3%     #显示第6个字符以后的3个字符,即aa2
    echo %p:~0,3%     #显示前3个字符,即aa1
    echo %p:~-2%      #显示最后面的2个字符,即b2
    echo %p:~0,-2%     #显示除了最后2个字符以外的其它字符,即aa1bb1aa2b
    echo %p:aa=c%     #用c替换变量p中所有的aa,即显示c1bb1c2bb2
    echo %p:aa=%      #将变量p中的所有aa字符串置换为空,即显示1bb12bb2
    echo %p:*bb=c%     #第一个bb及其之前的所有字符被替换为c,即显示c1aa2bb2
    set p=%p:*bb=c%     #设置变量p,赋值为 %p:*bb=c% ,即c1aa2bb2
    set /a p=39      #设置p为数值型变量,值为39
    set /a p=39/10     #支持运算符,有小数时用去尾法,39/10=3.9,去尾得3,p=3
    set /a p=p/10     #用 /a 参数时,在 = 后面的变量可以不加%直接引用
    set /a p=”1&0″     #”与”运算,要加引号。其它支持的运算符参见set/?
    set p=        #取消p变量
    set /p p=请输入
    屏幕上显示”请输入”,并会将输入的字符串赋值给变量p
    注意这条可以用来取代 choice 命令
    注意变量在 if 和 for 的复合语句里是一次性全部替换的,如
    @echo off
    set p=aaa
    if %p%==aaa (
       echo %p%
       set p=bbb
       echo %p%
       )
    结果将显示
    aaa
    aaa
    因为在读取 if 语句时已经将所有 %p% 替换为aaa
    这里的"替换",在 /? 帮助里就是指"扩充"、"环境变量扩充"
    可以启用”延缓环境变量扩充”,用 ! 来引用变量,即 !变量名!
    @echo off
    SETLOCAL ENABLEDELAYEDEXPANSION
    set p=aaa
    if %p%==aaa (
       echo %p%
       set p=bbb
       echo !p!
       )
    ENDLOCAL
    结果将显示
    aaa
    bbb
    还有几个动态变量,运行 set 看不到
    %CD%        #代表当前目录的字符串
    %DATE%       #当前日期
    %TIME%       #当前时间
    %RANDOM%       #随机整数,介于0~32767
    %ERRORLEVEL%     #当前 ERRORLEVEL 值
    %CMDEXTVERSION%    #当前命令处理器扩展名版本号
    %CMDCMDLINE%     #调用命令处理器的原始命令行
    可以用echo命令查看每个变量值,如 echo %time%
    注意 %time% 精确到毫秒,在批处理需要延时处理时可以用到

    32 start
    批处理中调用外部程序的命令,否则等外部程序完成后才继续执行剩下的指令

    33 call
    批处理中调用另外一个批处理的命令,否则剩下的批处理指令将不会被执行
    有时有的应用程序用start调用出错的,也可以call调用

    34 choice (外部命令)
    选择命令
    让用户输入一个字符,从而选择运行不同的命令,返回码errorlevel为1234……
    win98里是choice.com
    win2000pro里没有,可以从win98里拷过来
    win2003里是choice.exe
    choice /N /C y /T 5 /D y>nul
    延时5秒

    35 assoc 和 ftype
    文件关联
    assoc 设置'文件扩展名'关联,关联到'文件类型'
    ftype 设置'文件类型'关联,关联到'执行程序和参数'
    当你双击一个.txt文件时,windows并不是根据.txt直接判断用 notepad.exe 打开
    而是先判断.txt属于 txtfile '文件类型'
    再调用 txtfile 关联的命令行 txtfile=%SystemRoot%system32NOTEPAD.EXE %1
    可以在"文件夹选项"→"文件类型"里修改这2种关联
    assoc      #显示所有'文件扩展名'关联
    assoc .txt    #显示.txt代表的'文件类型',结果显示 .txt=txtfile
    assoc .doc    #显示.doc代表的'文件类型',结果显示 .doc=Word.Document.8
    assoc .exe    #显示.exe代表的'文件类型',结果显示 .exe=exefile
    ftype      #显示所有'文件类型'关联
    ftype exefile   #显示exefile类型关联的命令行,结果显示 exefile="%1" %*
    assoc .txt=Word.Document.8
    设置.txt为word类型的文档,可以看到.txt文件的图标都变了
    assoc .txt=txtfile
    恢复.txt的正确关联
    ftype exefile="%1" %*
    恢复 exefile 的正确关联
    如果该关联已经被破坏,可以运行 command.com ,再输入这条命令

    36 pushd 和 popd
    切换当前目录
    @echo off
    c: & cd & md mp3    #在 C: 建立 mp3 文件夹
    md d:mp4       #在 D: 建立 mp4 文件夹
    cd /d d:mp4      #更改当前目录为 d:mp4
    pushd c:mp3      #保存当前目录,并切换当前目录为 c:mp3
    popd         #恢复当前目录为刚才保存的 d:mp4

    37 for
    循环命令
    这个比较复杂,请对照 for/? 来看
    for %%i in (c: d: e: f:) do echo %%i
    依次调用小括号里的每个字符串,执行 do 后面的命令
    注意%%i,在批处理中 for 语句调用参数用2个%
    默认的字符串分隔符是"空格键","Tab键","回车键"
    for %%i in (*.txt) do find "abc" %%i
    对当前目录里所有的txt文件执行 find 命令
    for /r . %%i in (*.txt) do find "abc" %%i
    在当前目录和子目录里所有的.txt文件中搜索包含 abc 字符串的行
    for /r . %%i in (.) do echo %%~pni
    显示当前目录名和所有子目录名,包括路径,不包括盘符
    for /r d:mp3 %%i in (*.mp3) do echo %%i>>d:mp3.txt
    把 d:mp3 及其子目录里的mp3文件的文件名都存到 d:mp3.txt 里去
    for /l %%i in (2,1,8) do echo %%i
    生成2345678的一串数字,2是数字序列的开头,8是结尾,1表示每次加1
    for /f %%i in ('set') do echo %%i
    对 set 命令的输出结果循环调用,每行一个
    for /f "eol=P" %%i in ('set') do echo %%i
    取 set 命令的输出结果,忽略以 P 开头的那几行
    for /f %%i in (d:mp3.txt) do echo %%i
    显示 d:mp3.txt 里的每个文件名,每行一个,不支持带空格的名称
    for /f "delims=" %%i in (d:mp3.txt) do echo %%i
    显示 d:mp3.txt 里的每个文件名,每行一个,支持带空格的名称
    for /f "skip=5 tokens=4" %%a in ('dir') do echo %%a
    对 dir 命令的结果,跳过前面5行,余下的每行取第4列
    每列之间的分隔符为默认的"空格"
    可以注意到 dir 命令输出的前5行是没有文件名的
    for /f "tokens=1,2,3 delims=- " %%a in ('date /t') do (
       echo %%a
       echo %%b
       echo %%c
       )
    对 date /t 的输出结果,每行取1、2、3列
    第一列对应指定的 %%a ,后面的 %%b 和 %%c 是派生出来的,对应其它列
    分隔符指定为 - 和"空格",注意 delims=- 后面有个"空格"
    其中 tokens=1,2,3 若用 tokens=1-3 替换,效果是一样的
    for /f "tokens=2* delims=- " %%a in ('date /t') do echo %%b
    取第2列给 %%a ,其后的列都给 %%b

    38 subst (外部命令)
    映射磁盘。
    subst z: serverd    #这样输入z:就可以访问serverd了
    subst z: /d      #取消该映射
    subst        #显示目前所有的映时

    39   xcopy (外部命令)
    文件拷贝
    xcopy d:mp3 e:mp3 /s/e/i/y
    复制 d:mp3 文件夹、所有子文件夹和文件到 e: ,覆盖已有文件
    加 /i 表示如果 e: 没有 mp3 文件夹就自动新建一个,否则会有询问

  • 转:vm下修改硬盘大小的方法

    2009-07-17 15:57:20

    调整VMware虚拟机硬盘容量大小

             担心创建的虚拟机硬盘容量太大会占用真正的硬盘空间,把硬盘的容量设置得很小,可是等到给虚拟机装好系统后再装其他的软件,才发现硬盘容量不够用了。如果重建虚拟机,还要重新再装一遍操作系统,非常麻烦,而VMware中又不能直接修改虚拟机的硬盘容量大小,真是麻烦。经过多方请教高人,终于找到了解决之道。其实在VMware安装目录下就有一个vmware-vdiskmanager.exe程序,它是一个命令行工具,可用来修改虚拟机硬盘的大小。方法如下:
    第一步:按Win+R键调出运行对话框,输入“cmd”并按回车键启动命令提示符窗口。

    第二步:进入VMware的安装目录(比如我的安装目录为:D:ProgramFilesVMwarelVMware Workstation),在命令提示符后输入"vmware-vdiskmanager",什么参数也不加直接按回车键,可显示这一命令的说明。

    第三步:参考说明,执行类似下面的命令:vmware-vdiskmanager -x l6Gb "DVMwareWinXPWindows XP Professional.vmdk" 参数"-X"表示要扩展虚拟机硬盘空间,紧随其后的数字是要扩展的大小(本例为扩展到16GB,这是一个磁盘总量,包含了原先的磁盘容量)。最后是指定要操作的虚拟机磁盘的具体文件,因为路径名中有空格,所以必须以双引号括起来。按回车键开始执行,执行完毕,退出命令提示符窗口,重启VMware,会发现虚拟机硬盘空间已变成16GB了。

  • QTP测试修改脚本之 修改对象

    2009-02-04 15:58:57

    以qtp自带的定机票网页来进行举例:

    在定完机票后,有两个按钮可以选择,一个是"back to flights",另一个是“back to home”,在录制脚本时,选择的是“back to home”,录制完成的脚本如下: 下面部分省略

    Browser("Welcome: Mercury Tours").Page("Book a Flight: Mercury").WebEdit("creditnumber").Set "88888888"
    Browser("Welcome: Mercury Tours").Page("Book a Flight: Mercury").WebCheckBox("ticketLess").Set "ON"
    Browser("Welcome: Mercury Tours").Page("Book a Flight: Mercury").Image("buyFlights").Click 69,8
    Browser("Welcome: Mercury Tours").Page("Flight Confirmation: Mercury").Image("home").Click

    在qtp的keyword view 中item字段查看到的对象为“home”

    2、实际操作时,我们需要将此处修改为“点击的是back to flight按钮,以便可以重复定票”

    3、操作:点击home后面的下拉箭头,选择"object from repository",则弹出slect object for step对话框。点击“手型图片”选中 对应网页的“back to flight”按钮,确定后即可。

    脚本即为:

    Browser("Welcome: Mercury Tours").Page("Flight Confirmation: Mercury_2").Image("backtoflights").Click

     

    重新回放,即可以反馈到对应的网页。。

     

    以上是我找到的修改方法,如果大家有更好的方法,记得告诉我哈

     

     

  • QTP9.5版本的delphi插件

    2009-02-04 15:22:35

    找到一个9.5的delphi插件,放上来,,需要的可以下载
  • QTP测试Delphi项目点滴记载-添加对象

    2009-02-04 15:18:07

    我的qtp是9.2的版本,没有安装delphi的插件,故qtp不能识别delphi的很多控件,导致,录制的时候可以录制成功,但是回放的时候始终不能识别到相应的对象,就需要用qtp的Object Identification工具进行对象的添加。

    步骤:

    1、录制后察在keyword view中,找到那个你需要自定义的控件所在的条目,点右键,有一个object propertys,看一下里面的条目,大部分默认使用window id做识别。这个delphi由于有些不是window的标准控件,故这个市没有用的。。这一步需要记录下属性中的nativeclass值,如“edit”

    2、打开Object Identification工具,点击“User-Defined”,在弹出的对话框class name中输入刚才记录下的名称“Edit”,后面选择其继承于“map to”,在下拉框中找到其父类。如改处的编辑框,其父类选择:singline edit

    3、在自定义的控件Assisive Properties 中选择x  y (表示控件的坐标,相对值),删除windows id项

    4、完成设置后确定,重新录制后,就可以回放成功了。

     

     

    以后操作适用于QTP不能识别的控件的自定义

  • sql查询后排序

    2008-09-25 14:51:30

    降序:
    select * from 表 Order by 字段 DESC

    升序:
    select * from 表 Order by 字段 ASC

    也可以多个字段分别先后排序.只要在order by 后面分别先后写出就行了.
    如:select * from 表 Order by 字段1 ASC,字段2 ASC,字段3 DESC

    有时候一个表的数据太多。。我们需要对排序后的数据取前100条 ,可以采用下面语句

    select top 100 * from 表 order by 字段 desc(asc) 

     

  • 向一个表中插入多条语句

    2008-09-25 14:44:49

    有时候需要向一个表中插入多条数据,常用方法为用循环实现:

    例:

    declare   @t   int  
    set   @t=6  
    while(@t<10000)  
    begin
    SET   IDENTITY_INSERT   tAdd  ON  
    insert into tadd(sCardid,cRemain,sFilling,sName,sDis,sCardType,wbbh,sfsc,idCounter)
              values('111',10, '', '', '','计费卡','001001', '',@t)

    select @t=@t+1
    end

     

    其中idCounter 由于是自增型的数据类型,如果需要对它进行写入操作,则需要加入:

    SET   IDENTITY_INSERT   tAdd  ON  

  • 批处理命令学习1

    2008-09-11 11:42:21

     

    杀进程
    taskkill /f /im 进程名

    删除文件

    del c:\a.txt

  • 修改npptools.dll 防止ARP

    2008-08-06 13:49:16

    修改npptools.dll 防止ARP
    2008-02-29 01:11
    做母盘的时候把下面一段文件放在BAT里面运行下,或直接手动把c:\windows\system32\npptools.dll 这个文件设置所有用户拒绝.


    @echo
    @cacls c:\windows\system32\npptools.dll /e /t /d Administrators
    @cacls c:\windows\system32\npptools.dll /e /t /d admin
    @cacls c:\windows\system32\npptools.dll /e /t /d "Power Users"
    @cacls c:\windows\system32\npptools.dll /e /t /d System
    @cacls c:\windows\system32\npptools.dll /e /t /d users
  • inno setup 学习-创建窗体并将获取到字符存入指定文件

    2008-07-28 15:28:15

    1、窗体的创建可以完全通过工具inno Setup Form Designer 实现,这里就不多讲了,

    2、一般创建窗体的目的都是要通过安装过程中用户输入部分安装信息,第一步已经解决了信息的和uoq

    接下来就需要解决信息的存储了。

    通常在安装程序结束后,会调用 procedure DeinitializeSetup()函数,在该函数中就可以将信息输入指定文件中,具体请参照下面的:

     procedure DeinitializeSetup();
      begin
        SetIniString('Center', 'Addr', InfoEdit1.text, ExpandConstant('{app}\test.ini'));  //将从窗体infoedit1获得的文字信息输入到test文件中
        SetIniString('Center', 'Port', InfoEdit2.text, ExpandConstant('{app}\test.ini'));
        SetIniString('SzoneID', 'Provin', InfoEdit3.text, ExpandConstant('{app}\test.ini'));
        SetIniString('SzoneID', 'City', InfoEdit4.text, ExpandConstant('{app}\test.ini'));
        SetIniString('Dir', 'Dir', ExpandConstant('{app}'), ExpandConstant('{app}\test.ini'));

      end;

    安装结束后,在{app}目录中生成一个test.ini文件

    其内容为:

    [Center]
    Addr=192.168.1.1
    Port=2625
    [SzoneID]
    Provin=cesh
    City=tewt
    [Dir]
    Dir=C:\Program Files\test  ////

     

  • inno setup 学习-样本

    2008-07-28 11:38:44

    转至:http://hi.baidu.com/yanjinbin/blog/item/2a55d88890a24890a4c272d6.html

     

    ; 脚本由 Inno Setup 脚本向导 生成!
    ; 有关创建 Inno Setup 脚本文件的详细资料请查阅帮助文档!

    [Setup]
    ; 注: AppId的值为单独标识该应用程序。
    ; 不要为其他安装程序使用相同的AppId值。
    ; (生成新的GUID,点击 工具|在IDE中生成GUID。)
    AppId={{A9861883-31C5-4324-BD9A-DC3271EEB675}
    ;程序名
    AppName=ISsample
    ;版本号
    AppVerName=ISsample 1.0.0.0
    ;发布者名
    AppPublisher=Hkiss
    ;相关连接
    AppPublisherURL=http://www.yan.com/
    AppSupportURL=http://www.yan.com/
    AppUpdatesURL=http://www.yan.com/
    ;默认安装目录
    DefaultDirName={pf}\ISsample
    ;默认开始菜单名
    DefaultGroupName=ISsample
    ;是否打开->可选安装开始菜单项
    ;AllowNoIcons=yes
    ;安装协议
    ;LicenseFile=C:\Example\原始文件\agreement.txt
    ;安装前查看的文本文件
    ;InfoBeforeFile=C:\Example\原始文件\Setup_New.txt
    ;安装后查看文本文件
    ;InfoAfterFile=C:\Example\原始文件\Setup_Old.txt
    ;输出文件夹
    OutputDir=C:\Example\InnoSetup\out
    ;输出文件名
    OutputBaseFilename=setup
    ;安装图标
    SetupIconFile=C:\Example\原始文件\title.ico
    ;安装需要输入密码
    ;Password=123
    ;Encryption=yes

    ;压缩相关
    Compression=lzma
    SolidCompression=yes

    ;可以让用户忽略选择语言相关
    ShowLanguageDialog = yes
    ;备注版本信息
    VersionInfoCompany=HTTP://www.Hkiss.COM
    VersionInfoDescrīption=ISsample 汉化增强版
    VersionInfoVersion=1.0.0.0
    VersionInfoCopyright=Copyright (C) 2007-2008 Hkiss

    ;制作选择语言
    [Languages]
    Name: "chs"; MessagesFile: "compiler:Default.isl" ;LicenSeFile :"C:\Example\原始文件\chs\agreement.txt"
    Name: "en"; MessagesFile: "compiler:Languages\English.isl";LicenSeFile :"C:\Example\原始文件\en\agreement.txt"

    ;用户定制任务
    [Tasks]
    Name: "desktopicon"; Descrīption: "{cm:CreateDesktopIcon}"; GroupDescrīption: "{cm:AdditionalIcons}"; Flags: unchecked
    Name: "quicklaunchicon"; Descrīption: "{cm:CreateQuickLaunchIcon}"; GroupDescrīption: "{cm:AdditionalIcons}"; Flags: unchecked
    Name: "Tasks_1" ; Descrīption:"用户自定义任务1"; Flags: unchecked
    Name: "Tasks_2" ; Descrīption:"用户自定义任务2"; Flags: unchecked
    ;选择了组件才会出现的定制任务
    Name: "Tasks_3" ; Descrīption:"用户自定义任务3";Components: c1 ; Flags: unchecked

    ;文件安装
    [Files]
    ;多语言安装环境设置    公共参数Languages 来设置
    Source: "C:\Example\原始文件\enfile.txt"; DestDir: "{app}"; Languages: en ; Flags: ignoreversion
    Source: "C:\Example\原始文件\chsfile.txt"; DestDir: "{app}"; Languages: chs ; Flags: ignoreversion
    ;用户自定义任务 Tasks
    Source: "C:\Example\原始文件\Tasks\tasks_1.txt"; DestDir: "{app}\Tasks"; Flags: ignoreversion ;Tasks : Tasks_1
    Source: "C:\Example\原始文件\Tasks\tasks_2.txt"; DestDir: "{app}\Tasks"; Flags: ignoreversion ;Tasks :Tasks_2
    Source: "C:\Example\原始文件\Tasks\tasks_Components.txt"; DestDir: "{app}\Tasks"; Flags: ignoreversion ;Tasks :Tasks_2
    ;用户定义组件安装
    Source: "C:\Example\原始文件\Components\Components_1.txt"; DestDir: "{app}\Components"; Flags: ignoreversion ; Components: a1;
    Source: "C:\Example\原始文件\Components\Components_2.txt"; DestDir: "{app}\Components"; Flags: ignoreversion ; Components: a2;
    Source: "C:\Example\原始文件\Components\Components_3.txt"; DestDir: "{app}\Components"; Flags: ignoreversion ; Components: a3;
    Source: "C:\Example\原始文件\Components\Components_4.txt"; DestDir: "{app}\Components"; Flags: ignoreversion ; Components: a1 a2 a3;

    ;用户注册自定义Dll文件      regserver 注册 noregerror 不显示错误信息
    Source: "C:\Example\原始文件\jmail.dll"; DestDir: "{app}"; Flags: ignoreversion regserver
    ;添加自述文件
    Source: "C:\Example\原始文件\ISsample.txt"; DestDir: "{app}"; Flags: ignoreversion
    ;添加一个文件到缓存文件夹{Tmp} deleteafterinstall 安装后删除
    Source: "C:\Example\原始文件\test.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall

    Source: "C:\Example\原始文件\ISsample.chm"; DestDir: "{app}"; Flags: ignoreversion
    Source: "C:\Example\原始文件\ISsample.exe"; DestDir: "{app}"; Flags: ignoreversion
    Source: "C:\Example\原始文件\ISsample.dll"; DestDir: "{app}"; Flags: ignoreversion
    Source: "C:\Example\原始文件\ISsample.ini"; DestDir: "{app}"; Flags: ignoreversion
    Source: "C:\Example\原始文件\ISsample.rar"; DestDir: "{app}"; Flags: ignoreversion
    Source: "C:\Example\原始文件\ISsample_sys.dll"; DestDir: "{win}\System32"; Flags: ignoreversion
    Source: "C:\Example\原始文件\log\*"; DestDir: "{app}\log"; Flags: ignoreversion recursesubdirs createallsubdirs
    ; 注意: 不要在任何共享系统文件上使用“Flags: ignoreversion”
    ;安装类型设置
    [Types]
    Name: Full ;Descrīption:"完全安装"; Flags: iscustom
    Name: Compact ;Descrīption:"简洁安装";
    Name: Custom; Descrīption:"自定义安装";
    ;组件安装
    [Components]
    Name: c1; Descrīption: "自定义任务3" ; Types: Full
    Name: a1; Descrīption: "安装Components_1"; Types: Full Compact Custom ;
    Name: a2; Descrīption: "安装Components_2"; Types : Full   Compact
    Name: a3; Descrīption: "安装Components_3"; Types : Full

    ;开始菜单,桌面快捷方式
    [Icons]
    Name: "{group}\ISsample"; Filename: "{app}\ISsample.exe"
    Name: "{group}\{cm:ProgramOnTheWeb,ISsample}"; Filename: "http://www.yan.com/"
    Name: "{group}\{cm:UninstallProgram,ISsample}"; Filename: "{uninstallexe}"
    Name: "{commondesktop}\ISsample"; Filename: "{app}\ISsample.exe"; Tasks: desktopicon
    Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\ISsample"; Filename: "{app}\ISsample.exe"; Tasks: quicklaunchicon
    ;添加一个帮助文挡
    Name: {group}\ISsample 1.0.0.0 帮助文档;Filename: {app}\ISsample.chm

    ;用来在程序安装完成后 在安装程序显示最终对话框之前执行程序 常用与运行主程序 显示自述文件 删除临时文件
    [Run]
    Filename: "{app}\ISsample.exe"; Descrīption: "{cm:LaunchProgram,ISsample}"; Flags: nowait postinstall skipifsilent
    Filename: "{app}\ISsample.txt"; Descrīption: "查看显示自述文件"; Flags: postinstall skipifsilent shellexec

    ;更改显示在程序中显示的消息文本
    [Messages]
    BeveledLabel=HKiss科技
    ;卸载对话框说明
    ConfirmUninstall=您真的想要从电脑中卸载ISsample吗?%n%n按 [是] 则完全删除 %1 以及它的所有组件;%n按 [否]则让软件继续留在您的电脑上.
    ;定义解压说明
    ;StatusExtractFiles=解压并复制主程序文件及相关库文件...

    ;用与在用户系统中创建,修改或删除注册表健值
    [Registry]
    Root: HKLM ;SubKey:"Software\ISsample";ValueType:dword;ValueName:config;ValueData:10 ;Flags:uninsdeletevalue
    ;在执行脚本
    [code]
    //全局变量
    var MyProgChecked: Boolean;

    //判断程序是否存在


    //初始华程序事件
    function InitializeSetup(): boolean;
    var Isbl: boolean;         //声明变量
    var Isstr: string;
    begin       //开始
    Isbl := true;             //变量赋值
    Isstr := '欢迎';
    if RegValueExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\ISsample', 'config') then
    begin
        MsgBox('已安装过,请先卸载在安装',mbConfirmation, MB_OK);
        isbl := false;
    end else
    begin
       //MsgBox('无值',mbConfirmation, MB_OK);
         isbl := true;
    end;

    //下面是个麻烦的 条件语句 end else 注意
    //if MsgBox(Isstr, mbConfirmation, MB_OKCANCEL) = IDOK then
    //begin
    // isbl := true;
    // MsgBox('执行了', mbConfirmation, MB_OK);
    //end else
    //begin
    // isbl := false;
    //MsgBox('执行了', mbConfirmation, MB_OK);
    //end;

    Result := Isbl;
    end;       //结束

    procedure CurStepChanged(CurStep: TSetupStep);
    var Isstr :string;
    begin
    if CurStep=ssInstall then       //实际安装前调用
    begin
        //MsgBox('CurStepChanged:实际安装前调用', mbConfirmation, MB_OKCANCEL);           //安装完成后调用
    end;
    if CurStep=ssPostInstall then
    begin
        Isstr := ExpandConstant('{tmp}\tmp.rar');
    //    if FileExists(Isstr) then
    //    begin
    //      MsgBox('文件存在',mbConfirmation, MB_OK);
    //    end else
    //    begin
    //      MsgBox('文件不存在',mbConfirmation, MB_OK);
    //    end;
       // MsgBox('CurStepChanged:实际安装后调用', mbConfirmation, MB_OKCANCEL);
    end;
    end;

    //下一步 按钮按钮 事件
    function NextButtonClick(CurPageID: Integer): Boolean;
    var ResultCode: Integer;
    var IsSetup : Boolean;
    begin
    IsSetup := true ;
    case CurPageID of
        wpSelectDir:
           MsgBox('NextButtonClick:' #13#13 'You selected: ''' + WizardDirValue + '''.', mbInformation, MB_OK);   //WizardDirValue路径
        wpSelectProgramGroup:
           MsgBox('NextButtonClick:' #13#13 'You selected: ''' + WizardGroupValue + '''.', mbInformation, MB_OK); //开始菜单名
        wpReady:
          begin
           if not RegValueExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Test', 'config') then   begin
              if MsgBox('程序执行需要Test.ext,是否安装!', mbConfirmation, MB_YESNO) = idYes then begin
               ExtractTemporaryFile('test.exe');
                if not Exec(ExpandConstant('{tmp}\test.exe'), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then
                  MsgBox('Test.exe出错:' #13#13 ' ' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK);
              end else begin
                    IsSetup := false ;
              end ;
              BringToFrontAndRestore();
            end;
          end;
    end;
    Result := IsSetup;
    end;

  • LR学习点滴记录-socket脚本学习1

    2008-07-21 14:51:07

    网上搜索时看到一篇好的实例,复制下来,保存:

    用LoadRunner编写socket应用的测试脚本

            LoadRunner提供了很好的对socket应用的支持,用户可以通过录制方法完全获得客户端发送和接收的数据,然后在录制的基础上对相应的数据进行参数化和关联等处理。

            但在有些情况下(例如,客户端程序没有windows上的版本),我们就很难通过录制达成生成脚本的目标了。但如果我们能够完全知晓服务端和客户端的交互过程,完全手工编写一个测试脚本也并不是一件特别困难的事情。

           在本文中,我们以一个实际的例子说明如何根据服务端和客户端交互的过程,用LoadRunner自行编写相应的脚本。

            以下是服务端工作线程的代码:
    DWORD WINAPI mythread( LPVOID lpParameter)    //客户线程
    {
        
    struct My my;
        memcpy(
    &my,lpParameter,sizeof(My));    
        printf(
    "One client connect!\n");
        
    char str1[1024];            //接收字符串
        char str2[1024];
                            
        
    int i;
        i
    =recv(my.skt,str1,sizeof(str1),0);    //接收客户请求
        str1[i]=0;

        
    char *filename;
        filename
    =new char[255];
        
    for(int j=2;j<i;j++)            //获得文件名
        {
            filename[j
    -2]=str1[j];
        }
        filename[i
    -2]=0;
       

        
    if (str1[0]=='S')
        {
            printf(
    "The file name : %s\n",filename);
            ofstream 
    out(filename);                //创文件流   
            if (!out)
            {
                printf(
    "cannot open file.\n");        //文件是否正确打开,打开错误则退出
                send(my.skt,"q",1,0);            //向客户发送退出信息
                closesocket(my.skt);            //解除客户连接;
                return 0;
            }
            str2[
    0]='O';                       
            str2[
    1]='K';
            str2[
    2]=0;
            send(my.skt,str2,strlen(str2),
    0);        //回复OK信息

            i
    =recv(my.skt,str1,sizeof(str1),0);        //接收文件长度
            str1[4]=0;
           
            
    int len;
            len
    =str1[0]*1000+str1[1]*100+str1[2]*10+str1[3];
            printf(
    "The File lenght is: %d Byte\n",len);
           
            
    for(int j=0;j<len;j++)
                {
                    
    char str[1];
                    i
    =recv(my.skt,str,sizeof(str),0);//接收文件,按字节接收,接收字符串为2个字节
                    str[i]=0;
                    
    out.put(str[0]);
                }

            
    out.close();                    //关闭文件
            printf("over!One client quit!\n");        //接收文件完毕
            closesocket(my.skt);                //解除此客户连接
            return 0;
        }

        
    if (str1[0]=='R')
        {       
           
            ifstream 
    in(filename);
            
    if (!in)
            {
                printf(
    "cannot open file or file not exist.\n");    //文件是否正确打开,打开错误则退出
                send(my.skt,"q",1,0);                    //向客户发送退出信息
                closesocket(my.skt);                    //解除客户连接;
                return 0;
            }
            
    char ch;
            
    int len=0;
            
    while(in.get(ch))
            {
                len
    ++;                            //get file lenght
            }
            
    in.close();
            str2[
    0]='O';
            str2[
    1]='K';
            str2[
    2]=len/1000;                       
            str2[
    3]=(len%1000)/100;
            str2[
    4]=(len%100)/10;
            str2[
    5]=len%10;
            printf(
    "%s",str2);
            send(my.skt,str2,
    6,0);                        //发OK+文件长度

            
    in.open(filename);
            
    if (!in)
            {
                printf(
    "cannot open file or file not exist.\n");    //文件是否正确打开,打开错误则退出
                send(my.skt,"q",1,0);                    //向客户发送退出信息
                closesocket(my.skt);                    //解除客户连接;
                return 0;
            }

            
    while(in.get(ch))                        //发文件
            {               
                
    char str[1];
                strcpy(str,
    "");
                str[
    0]=ch;
                str[
    1]=0;
                send(my.skt,str,
    1,0);                    //发送一个字符
            }
            
    in.close();
            printf(
    "over,One client quit!\n");                //传输文件完毕
            closesocket(my.skt);                        //解除此客户连接
            return 0;
        }

        printf(
    "Bad command!\n");
        closesocket(my.skt);
        
    return 0;
    }

            从这段代码中可以看到,当客户端和服务端建立连接后,客户端会先向服务端发送一个请求,该请求的第一个字节是大写的“S”或是“R”,分别向服务端写文件或是从服务端读取文件。从第三个字节开始,后面的内容是请求文件的文件名。

            服务端在接收到客户端的请求后,根据请求的类型,如果是“S”,则打开指定的文件,并返回一个字符串“OK”;如果是“R”,则打开指定的文件并向客户端发送“OK”+“文件长度”。

            随后,如果是“S”,则由客户端发送写入的文件长度和文件内容给服务端;如果是“R”,则向客户端发送文件的内容。

            到此我们已经完全明了了客户端和服务端的交互过程,因此,我们可以尝试在LR中建立一个脚本用户模拟客户端行为。

            下面我们以“S”的处理过程为例编写脚本。

            1、打开VUGen应用;
            2、新建脚本,选择“windows sockets”协议,不需录制;
            3、在Action Section中增加以下内容:
        //建立到服务端的连接
        lrs_create_socket("socket1","TCP","RemoteHost=127.0.0.1:8000",LrsLastArg);
       
        
    //发送“S”和文件名
        lrs_send("socket1""buf0", LrsLastArg);
        lrs_receive(
    "socket1""buf1", LrsLastArg);
       
        
    //发送要写入的数据的长度
        lrs_send("socket1""buf2", LrsLastArg);

        
    //发送数据内容
        lrs_send("socket1""buf3", LrsLastArg);
       
        
    //关闭连接
        lrs_close_socket("socket1");
       
            4、这样就成功的描述了整个交互过程,但还没有给出实际要发送的数据。在采用“Windows Sockets”协议的脚本中,实际发送的数据存放在data.ws Section中,因此,打开该Section,直接输入:
    send  buf0 7
        
    "S"
        
    "\x00"
        
    "1.txt"

    recv buf1 
    2
        
    "OK"

    send buf2 
    3
        
    "\x00"
        
    "\x00"
        
    "\x02"
        
    "\x00"

    send buf3 
    20
        
    "12345678901234567890"

            每个发送和接收的数据包在这里都有登记,“send”和“recv”表示数据的方向;“buf0”等表示数据包的描述,和脚本中的内容对应;接下来的一个整数表示数据包的长度;然后是数据包的内容,“\x00”表示16进制的00。

            该脚本描述了客户端向服务端请求写入一个文件1.txt,文件内容为“12345678901234567890”的过程。

           
          
  • LR学习点滴记录-IP Wizard使用

    2008-07-21 14:16:06

    LoadRunner 使用虚拟IP测试流程,设置虚拟IP地址:
     
    1、load Generator机器必须使用固定的IP,不能使用动态IP.确定网络中不冲突的IP地址
     
    2、打开:开始-〉程序-〉loadrunner-〉tools-〉ip wizard.
     
      第一项:增加新IP选择第一项;

       第二项:使用保存的文件增加IP选择

      第三项:释放已经设置的IP。
     
     点“下一步”

    3、此步让输入web server的IP地址,尚不清楚有何意义。不输入,直接点‘下一步’。
     
    4、点击add,增加虚拟ip

       点击remove按钮可以删除选定的虚拟IP.
     
    5、点击add后,在对话框中根据输入的IP的第一个值和数量,自动添加到虚拟IP列表中。

      例如:192.168.67.140  4,则增加的虚拟IP是:192.168.67.140、192.168.67.141、192.168.67.142、192.168.67.143.点ok按钮。点”完成“按钮。
     
      说明:使用Save as…可以将本次增加的IP保存成。ips文件,下次再使用时就可以直接选择此文件了。
     
      点‘OK’按钮即可
     
    6、重新启动计算机(可以重新启动网络连接即可)
     
      注意: 重新启动计算机后,设置的虚拟IP都生效了,此时使用ping会发现都能ping通,并且本机的IP也被改成了第一个虚拟IP地址。确认虚拟IP是否都生效的方法:在运行中输入cmd,在命令窗口录入ipconfig/all,然后就能看到已经生效的所有IP.
     
      使用虚拟IP(以手动方案为例)

      在controller中,选择 Scenario-〉Enable IP Spoofer,此项设置允许使用IP欺骗。按Generators按钮,设置虚拟用户生成器,将虚拟IP地址都添加进去,并连通。连接成功的虚拟用户生成器会在工具栏中显示。
     
    7、测试完成后,需要释放所有的虚拟ip并重新启动计算机。
     
      使用虚拟IP测试完成后 ,打开IP Wizard,释放所有虚拟IP.重新启动计算机。

     

  • LR学习点滴记录-socket录制关联

    2008-07-18 11:04:24

    转:

    今天写一下winsock的关联操作。

    以前看过一个文档。在英文版的讲winsock的,其中讲到关联。大致操作是:

    1,录制。

    2,回放。这里是失败。

    3,data.ws里找需要关联的数据。

    4,F7,打开EBCDIC translation对话框。

    5,查找数据的位置及偏移量。

    6,到脚本中写函数用:lrs_save_param, lrs_save_param_ex, lrs_save_searched_string,这三个函数。

     

    Notes:winsock的关联函数要写到需要关联的代码行的下面。

     

    说明一下这几个函数:

    Lrs_save_param:

    int lrs_save_param ( char *s_desc,char *buf_desc, char *param_name, int offset, int param_len);

    这个函数保存buffer中的数据到一个参数里。这个函数是用来在脚本中做关联的。

    前两个参数是为了指定特定的参数。

    在指定活动的socketbuffer之后,需要指定一个参数来保存数据。指定偏移量来显示buffer中数据的偏移量和数据的长度。

    保存了参数之后,可以在脚本和数据文件使用它,代替所有需要替代的值。替换时要用选项中的定义的符号来引用。

    注意:要从buffer中保存一个编码过的数据到参数中,要用lrs_save_param_ex函数。

    lrs_save_param_ex

    int lrs_save_param_ex ( char *s_desc, char *type, char *buff, int offset, int length, char *encoding, char *param );

    这个函数保存一个buffer或者一个buffer的某一部分到参数中。这个变量指定buffer中某种类型的数据被保存:用户buffer,录制的buffer,或者上一个接收到的buffer.推荐使用在用户数据中。

    [Z1] 

     

     

    下面说不用这么麻烦的操作的,直接点几下就可以了。

     

    1         录制脚本

    这个没什么说的吧。选择协议winsock,这要是也不懂,我建议你去看十遍手册。

    我这里录制到的脚本如下:

           lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=192.168.1.114:5560", LrsLastArg);

           lrs_send("socket0", "buf0", LrsLastArg);

           lrs_receive("socket0", "buf1", LrsLastArg);

           lrs_create_socket("socket1", "TCP", "LocalHost=0", "RemoteHost=192.168.1.114:5560", LrsLastArg);

           lrs_send("socket1", "buf2", LrsLastArg);

           lrs_receive("socket1", "buf3", LrsLastArg);

    相应的data.ws如下:

    ;WSRData 2 1

     

    send buf0 50

           "OPERTYPE(LOGIN)ACCOUNTNAME(admin)PASSWORD(admin)"

     

    recv buf1 155

           "DATALEN{{155}}000000USERID{{90}}USERNAME{{DMS"

           "\xcf\xb5\xcd\xb3"

           "WEB"

           "\xb2\xe9\xd1\xaf\xd5\xca\xbb\xa7"

           "}}USERDESCRIBE{{"

           "\xba\xfe\xd6\xdd\xb5\xe7\xc1\xa6\xbe\xd6"

           "\\DMS"

           "\xcf\xb5\xcd\xb3"

           "WEB"

           "\xb2\xe9\xd1\xaf\xd5\xca\xbb\xa7"

           "}}DEPARTNAME{{"

           "\xce\xb4\xd6\xaa"

           "}}ADMIN{{0}}CLIENTSESSIONID{{2}}"

     

    send buf2 53

           "CLIENTSESSIONID(2)OPERTYPE(INITDEPARTLIST)"

     

    recv buf3 683

           "DATALEN{{683}}000000XMLDATA{{<?xml version=\"1.0\" encoding=\"GB2312\"?>\n"

           "<!DOCTYPE DepartList>\n"

           "<DepartList>\n"

           ………………………………………………………………………………………………

    这里就省略了些数据。反正也看着也晕乎乎的。

    这里说明一下,我这里是用GIS系统,需要sessionID关联的。我这上面的代码很简单,在buf1中有一个sessionID,在buf2send时就用到了它。

    2         回放一下

    在不关联时回放是一定会有问题的。我回放的结果是:

    Virtual User scrīpt started

    Starting action vuser_init.

    Ending action vuser_init.

    Running Vuser...

    Starting iteration 1.

    Starting action Action.

    Action.c(4): lrs_create_socket(socket0, TCP, ...)

    Action.c(6): lrs_send(socket0, buf0)

    Action.c(8): lrs_receive(socket0, buf1)

    Action.c(11): lrs_create_socket(socket1, TCP, ...)

    Action.c(13): lrs_send(socket1, buf2)

    Action.c(15): lrs_receive(socket1, buf3)

    Action.c(15): Mismatch (expected 683 bytes, 42 bytes actually received)

    Action.c(17): lrs_create_socket(socket2, TCP, ...)

    Action.c(19): lrs_send(socket2, buf4)

    Action.c(21): lrs_receive(socket2, buf5)

    Action.c(21): Mismatch (expected 34143 bytes, 42 bytes actually received)

    Action.c(23): lrs_create_socket(socket3, TCP, ...)

    Action.c(25): lrs_send(socket3, buf6)

    Action.c(27): lrs_receive(socket3, buf7)

    Action.c(27): Mismatch (expected 100 bytes, 42 bytes actually received)

    Action.c(29): lrs_create_socket(socket4, TCP, ...)

    Action.c(31): lrs_send(socket4, buf8)

    Action.c(33): lrs_receive(socket4, buf9)

    Action.c(33): Mismatch (expected 134 bytes, 42 bytes actually received)

    Action.c(35): lrs_send(socket4, buf10)

    Action.c(38): lrs_receive(socket4, buf11)

    Action.c(38): Mismatch (expected 17520 bytes, 42 bytes actually received)

    Action.c(41): lrs_create_socket(socket5, TCP, ...)

    Action.c(43): lrs_send(socket5, buf12)

    Action.c(45): lrs_receive(socket5, buf13)

    Ending action Action.

    Ending iteration 1.

    Ending Vuser...

    Starting action vuser_end.

    Ending action vuser_end.

    Vuser Terminated.

    主要来看一下蓝色的部分,因为没有关联,服务器是返回了42字节的数据,但是和录制时的数据是不同的。所以会mismatch。这里可以在LOGMismatch的值打印出来,不过太长了,我就不打印了。^@^

    3         转到树视图做关联

    选择buf1看到数据:

    DATALEN{{155}}000000USERID{{90}}USERNAME{{DMS\xcf\xb5\xcd\xb3WEB\xb2\xe9\xd1\xaf\xd5\xca\xbb\xa7}}USERDESCRIBE{{\xba\xfe\xd6\xdd\xb5\xe7\xc1\xa6\xbe\xd6\\DMS\xcf\xb5\xcd\xb3WEB\xb2\xe9\xd1\xaf\xd5\xca\xbb\xa7}}DEPARTNAME{{\xce\xb4\xd6\xaa}}ADMIN{{0}}CLIENTSESSIONID{{2}}

    选择CLIENTSESSIONID{{2}}中的2.右击后选择:create parameter。在弹出窗口中。看到默认的是用lrs_save_param,这个函数只能关联固定长度的数据。如果是固定的话,到这里点击一下OK,就关联成功了。LR会自动生成语句并且提示检查其他的需要关联的地方。弹出一个窗口提示。

    而我这里的sessionID是动态的值。所以需要选择:extract parameter data using boundaries复选框。这时生成的语句是这样的:

    lrs_save_searched_string( "socket0", LRS_LAST_RECEIVED, "Parameter3", NULL, NULL, -1, 152, 1 );

    左右边界是NULL空的,这里点击left的浏览,弹出选择左边界的窗口,用鼠标选择:SESSIONID{{,点击Done

    再点击right浏览,选择}}

    就确定了左右边界了。

    这里的语句如下:

    lrs_save_searched_string("socket0",LRS_LAST_RECEIVED,"Parameter4","LB/BIN=SESSIONID{{", "RB/BIN=}}", 1, 0, -1);

    一路小跑点OK

    弹出提示是否替换所有符合左右边界的值。

    点击yesLR会自动搜索所有需要关联的地方并替换。

    再转到脚本视图,看到脚本如下:

      lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=192.168.1.114:5560", LrsLastArg);

           lrs_send("socket0", "buf0", LrsLastArg);

           lrs_receive("socket0", "buf1", LrsLastArg);  

       lrs_save_searched_string("socket0", LRS_LAST_RECEIVED, "Parameter1", "LB/BIN=SESSIONID{{", "RB/BIN=}}", 1, 0, -1);

        lr_output_message("小样还抓不到你!你不就是: %s嘛!",lr_eval_string("{Parameter1}"));       lrs_create_socket("socket1", "TCP", "LocalHost=0", "RemoteHost=192.168.1.114:5560", LrsLastArg);

           lrs_send("socket1", "buf2", LrsLastArg);

           lrs_receive("socket1", "buf3", LrsLastArg);

    看蓝色部分。后面一句输出是我加上去的。

    这样就关联成功了。

    4         再次回放

    看到LOG如下:

    Virtual User scrīpt started

    Starting action vuser_init.

    Ending action vuser_init.

    Running Vuser...

    Starting iteration 1.

    Starting action Action.

    Action.c(4): lrs_create_socket(socket0, TCP, ...)

    Action.c(6): lrs_send(socket0, buf0)

    Action.c(8): lrs_receive(socket0, buf1)

    Action.c(10): lrs_save_searched_string(socket0, get_last_received_buffer, Parameter1, LB/BIN=SESSIONID{{, RB/BIN=}}, 1, 0, -1)

    Action.c(12): 小样还抓不到你!你不就是: 8嘛!

    Action.c(14): lrs_create_socket(socket1, TCP, ...)

    Action.c(16): lrs_send(socket1, buf2)

    Action.c(18): lrs_receive(socket1, buf3)

    Action.c(20): lrs_create_socket(socket2, TCP, ...)

    Action.c(22): lrs_send(socket2, buf4)

    Action.c(24): lrs_receive(socket2, buf5)

    Action.c(26): lrs_create_socket(socket3, TCP, ...)

    Action.c(28): lrs_send(socket3, buf6)

    Action.c(30): lrs_receive(socket3, buf7)

    Action.c(32): lrs_create_socket(socket4, TCP, ...)

    Action.c(34): lrs_send(socket4, buf8)

    Action.c(36): lrs_receive(socket4, buf9)

    Action.c(38): lrs_send(socket4, buf10)

    Action.c(41): lrs_receive(socket4, buf11)

    Action.c(44): lrs_create_socket(socket5, TCP, ...)

    Action.c(46): lrs_send(socket5, buf12)

    Action.c(48): lrs_receive(socket5, buf13)

    Ending action Action.

    Ending iteration 1.

    Ending Vuser...

    Starting action vuser_end.

    Ending action vuser_end.

    Vuser Terminated.

    看,输出了:

    Action.c(12): 小样还抓不到你!你不就是: 8嘛!

     

     

     

    完。

     


     [Z1]这里还没写完。还有另一个函数解释。

  • LR学习点滴记录-错误日志查看

    2008-07-17 16:11:14

    1、在LR运行后生成的res文件夹里面。有log文件夹,里面有各个虚拟用户错误运行的记录。可以查看

    2、在analysis中可以通过查看.mdb这个文件来查看运行场景是出现的错误信息。

    用access打开.mdb,之后,选择Error message,最后打开。

    3、通过在.mdb文件中的修改,可以对lr的性能测试结果产生影响

  • LR学习点滴记录-参数设置

    2008-07-17 15:02:15

    转:

    一、关于参数的定义
    在你录制程序运行的过程中,脚本生成器自动生成由函数组成的用户脚本。函数中参数的值就是在录制过程中输入的实际值。
    例如,你录制了一个Web应用程序的脚本。脚本生成器生成了一个声明,该声明搜索名称为“UNIX”的图书的数据库。
    当你用多个虚拟用户和迭代回放脚本时,也许你不想重复使用相同的值“UNIX”。那么,你就可以用参数来取代这个常量。
    结果就是你可以用指定的数据源的数值来取代参数值。数据源可以是一个文件,也可以是内部产生的变量。
    用参数表示用户的脚本有两个优点:
    ① 可以使脚本的长度变短。
    ② 可以使用不同的数值来测试你的脚本。例如,如果你企图搜索不同名称的图书,你仅仅需要写提交函数一次。在回放的过程中,你可以使用不同的参数值,而不只搜索一个特定名称的值。
    参数化包含以下两项任务:
    ① 在脚本中用参数取代常量值。
    ② 设置参数的属性以及数据源。
    参数化仅可以用于一个函数中的参量。你不能用参数表示非函数参数的字符串。
    另外,不是所有的函数都可以参数化的。
    二、参数的创建
    可以指定名称和类型来创建参数。不存在对脚本中参数个数的限制。
    在Web程序的用户脚本中,你可以使用如下过程在基于文本的脚本视图中创建参数。或者,也可以在基于图标的树形视图中创建参数。
    要创建一个参数:
    1、 将光标定位在要参数化的字符上,点击右键。打开弹出菜单。
    2、 在弹出菜单中,选择“Replace with a Parameter”。选择或者创建参数的对话框弹出。
    3、 在“Parameter name”中输入参数的名称,或者选择一个在参数列表中已经存在的参数。
    4、 在“Parameter type”下拉列表中选择参数类型。
    5、 点击“OK”,关闭该对话框。脚本生成器便会用参数中的值来取代脚本中被参数化的字符,参数用一对“{}”括住。
    注意:在参数化CORBA或者General-Java 用户脚本的时候,必须参数化整个字符串,而不是其中的部分。
    另外注意:除了Web或者WAP,缺省的参数括号对于任何脚本都是 “{}”。你可以在“General Options”对话框中的“Parameterization”标签(Tools>General Options)中定义参数括号种类。
    6、 用同样的参数替换字符的其余情况,选中参数,点击右键,弹出菜单。从弹出的菜单中,选择“Replace More Occurrences”。搜索和替换对话框弹出。
    “Find What”中显示了你企图替换的值。“Replace With”中显示了括号中参数的名称。
    选择适当的检验框来匹配整个字符或者大小写。如果要搜索规则的表达式(.,!,?等等),选中“Regular Expression”检验框,然后点击“Replace”或者“Replace All”。
    注意:小心使用“Replace All”,尤其替换数字字符串的时候。脚本生成器将会替换字符出现的所有情况。
    7、 如果想用以前定义过的参数来替换常量字符串的话,选中该字符串,点击右键,然后选择“Use Existing Parameter”,子菜单“Use Existing Parameters”弹出。
    从子菜单“Use Existing Parameters”选择参数,或者用“Select from Parameter List”来打开参数列表对话框。
    注意:如果用以前定义过的参数来替换常量字符串的话,那么,使用“Parameter List”非常方便。同时,还可以查看和修改该参数的属性。
    8、 对于已经用参数替换过的地方,如果想取回原来的值,那么,就在参数上点击右键,然后选择“Restore Original Value”。
    在Web用户脚本的树形视图中创建参数
    在Web用户脚本的树形视图中创建一个参数的步骤
    1、将光标定位在企图参数化的地方,点击右键,从弹出的菜单中选择“Properties”。则相关的属性对话框打开。
    2、点击在要参数化的参量的旁边的“ABC”形状的图标。“Select or Create Parameter”对话框打开。
    3、在“Parameter name”中输入参数的名称,或者从列表中选择一个已经存在的参数。
    4、在“Parameter type”中输入参数的类型。
    5、点击“OK”关闭该对话框。用户脚本生成器会用参数来替换最初的字符串常量,并用一个表格形状的图标替换“ABC”形状的图标。
    6、要恢复参数化以前的值,点击图标,然后从弹出的菜单中选择“Undo Parameter”,则以前的值便会重现。
    三、定义参数的属性
    创建参数完成后,就可以定义其属性了。参数的属性定义就是定义在脚本执行过程中,参数使用的数据源。
    在Web用户脚本中,你既可以在基于文本的脚本视图中定义参数属性,也可以在基于图标的树形视图中定义参数属性。下面的过程将教你如何在基于本文的脚本视图中定义参数属性。
    定义参数属性步骤:
    1、 在参数上点击右键,有菜单弹出。
    2、 在弹出的菜单中,选择“Parameter Properties”。参数属性对话框打开,显示和当前参数类型相关的属性。
    3、 输入参数的属性值。
    4、 点击“Close”关闭参数属性对话框。
    在Web用户脚本的树形视图中定义参数的属性
    1、 将关标定位在参数上,然后点击右键,选择“Properties”。属性对话框打开。
    2、 点击要定义属性的参数旁边的表格形状按钮,点击右键,选择“Parameter Properties”。参数属性对话框打开,和参数类型相关的属性显示出来。
    3、 输入参数的属性。
    4、 点击“Close”关闭参数属性对话框。
    使用参数列表
    使用参数列表可以在任意时刻查看所有的参数,创建新的参数、删除参数,或者修改已经存在参数的属性。
    要使用参数列表:
    1、 点击参数列表按钮或者用“Vuser>Parameter List”。参数列表对话框打开。
    2、 要创建新的参数,点击“New”按钮。新的参数则被添加在参数树中,该参数有一个临时的名字,你可以给它重新命名,然后回车。
    注意:不要将一个参数命名为“unique”,因为这个名称是用户脚本生成器本身的。
    设置参数的类型和属性,点击“OK”,关闭参数列表对话框。
    注意:用户脚本生成器创建新的参数,但是不会自动用该参数在脚本中替换任意选中的字符串。
    3、 要删除已有的参数,那么,要先从参数树中选择该参数,点击“Delete”,然后确认你的行为即可。
    4、 要修改已有参数,那么,要先从参数树中选择该参数,然后编辑参数的类型和属性。
    四、理解参数的类型
    在你定义参数属性的时候,要指定参数值的数据源。你可以指定下列数据源类型的任何一种:
    Internal Data 虚拟用户内部产生的数据。
    Data Files 存在于文件中的数据。可能是已存在的文件或者是用脚本生成器新创建的。
    User-Defined Functions 调用外部DLL函数生成的数据
    Internal Data包括以下几种:
    1. Date/Time
    Date/Time用当前的日期/时间替换参数。要指定一个Date/Time格式,你可以从菜单列表中选择格式,或者指定你自己的格式。这个格式应该和你脚本中录制的Date/Time格式保持一致。
    2. Group Name
    Group Name 用虚拟用户组名称替换参数。在创建scenario的时候,你可以指定虚拟用户组的名称。当从用户脚本生成器运行脚本的时候,虚拟用户组名称总是None。
    3. Load Generator Name
    Load Generator Name用脚本负载生成器的名称替换参数。负载生成器是虚拟用户在运行的计算机。
    4. Iteration Number
    Iteration Number用当前的迭代数目替换参数。
    5. Random Number
    Random Number用一个随机数替换参数。通过指定最大值和最小值来设置随机数的范围。
    6. Unique Number
    Unique Number用一个唯一的数字来替换参数。你可以指定一个起始数字和一个块的大小。
    7. Vuser ID
    Vuser ID用分配给虚拟用户的ID替换参数,ID是由Loadrunner的控制器在scenario运行时生成的。如果你从脚本生成器运行脚本的话,虚拟用户的ID总是-1。
    五、数据文件
    数据文件包含着脚本执行过程中虚拟用户访问的数据。局部和全局文件中都可以存储数据。可以指定现有的ASCII文件、用脚本生成器创建一个新的文件或者引入一个数据库。在参数有很多已知值的时候数据文件非常有用。
    数据文件中的数据是以表的形式存储的。一个文件中可以包含很多参数值。每一列包含一个参数的数据。列之间用分隔符隔开,比如说,用逗号。
    对数据文件设置参数属性
    如果使用文件作为参数的数据源,必须指定以下内容:
    1. 文件的名称和位置
    2. 包含数据的列
    3. 文件格式,包括列的分隔符
    4. 更新方法
    如果参数的类型是“File”,打开参数属性(Parameter Properties)对话框,设置文件属性如下:
    1. 在“File path”中输入文件的位置,或者点击“Browse”指定一个已有文件的位置。缺省情况下,所有新的数据文件名都是“parameter_name.dat”,注意,已有的数据文件的后缀必须是.dat。
    2. 点击“Edit”。记事本打开,里面第一行是参数的名称,第二行是参数的初始值。使用诸如逗号之类的分隔符将列隔开。对于每一新的表行开始一行新的数据。
    注意:在没有启动记事本的情况下如果想添加列,就在参数属性对话框中点击“Add Col”,那么“Add new column”对话框就会弹出。输入新列的名称,点击“OK”。脚本生成器就会添加该列到表中,并显示该列的初始值。
    3. 在“Select Column”部分,指明包含当前参数数据的列。你可以指定列名或者列号。列号是包含你所需要数据的列的索引。列名显示在每列的第一行(row 0)。
    4. 在“Column delimiter”中输入列分隔符,你可以指定逗号、空格符等等。
    5. 在“First data line”中,在脚本执行的时候选择第一行数据使用。列标题是第0行。若从列标题后面的第一行开始的话,那就在“First data line”中输入1。如果没有列标题,就输入0。
    6. 在“Select next row”中输入更新方法,以说明虚拟用户在脚本执行的过程中如何选择表中的数据。方法可以是:连续的、随机的、唯一的、或者与其它参数表的相同行。
    7. 选中“Advance row each iteration”表示虚拟用户在每次迭代都使用新的一行数据而不是所有的迭代都使用相同的数据。
    从文件中更新参数值
    若使用文件中的数值,脚本生成器会要求你指定给参数分配数值给的方法。可用的方法有:
    1. 顺序(Sequential):该方法顺序地给虚拟用户分配参数值。如果正在运行的虚拟用户访问数据表的时候,它会取到下一行中可用的数据。
    2. 随机(Random):该方法在每次迭代的时候会从数据表中取随机数
    3. 使用种子取随机顺序(Use Random Sequence with Seed):如果从Loadrunner的控制器来运行scenario,你可以指定一个种子数值用于随机顺序。每一个种子数值在测试执行的时候代表了一个随机数的顺序。无论你何时使用这个种子数值,在scenario中同样的数据顺序就被分配给虚拟用户。如果在测试执行的时候发现了一个问题并且企图使用同样的随机数序列来重复测试,那么,你就可以启动这个功能(可选项)。
    4. 唯一(Unique):Unique方法分配一个唯一的有顺序的值给每个虚拟用户的参数。
    5. 与以前定义的参数取同一行(Same Line As <parameter>):该方法从和以前定义过的参数中的同样的一行分配数据。你必须指定包含有该数据的列。在下拉列表中会出现定义过的所有参数列表。注意:至少其中的一个参数必须是Sequential、Random或者Unique。
    如果数据表中有三列,三个参数定义在列表中:id1,name1和title1,如下:。
    ID Name Title
    132 Kim Manager
    187 Cassie Engineer
    189 Jane VP
    对于参数id1,你可以指示虚拟用户使用Random方法,而为参数name1和title1就可以指定方法“Same Line as id1”。所以,一旦ID“132”被使用,那么,姓名(Name)“Kim”和职位(Title)“Manager”同时被使用。
    六、从已存在的数据库中导入数据
    Loadrunner允许你利用参数化从已经存在的数据库中导入数据。可以使用下列两种方式之一:
    1. 使用Microsoft Query(要求在系统上先安装MS Query)。
    2. 指定数据库连接字符串和SQL语句。
    用户脚本生成器在从数据库中导入数据的过程中提供了一个向导。在向导中,你指明如何导入数据-通过MS Query创建查询语句或者直接书写SQL语句。在导入数据以后,以.dat为后缀并作为正规的参数文件保存。
    要开始导入数据库中数据的过程,在参数属性对话框中点击“Data Wizard”,则,数据库查询向导弹出。
    要创建新的查询
    1. 选择“Create new query”。如果需要MS Query的帮助,选择“Show me how to use Microsoft Query”,然后点击“Finish”。
    如果你还没有安装Microsoft Query,Loadrunner会提示你这个功能不可用。在进行之前,从Microsoft Office中安装MS Query。
    2. 在Microsoft Query中遵循以下步骤,导入期望的表和列。
    3. 在完成数据的导入后,选择“Exit and return to Virtual User Generator”,然后点击“Finish”。在参数属性对话框中数据库记录以data文件的形式显示出来。
    要在MS Query中编辑并查看数据,选择“View data or edit in Microsoft Query”。若要结束,则选择“File>Exit and return to Virtual User Generator”返回到脚本生成器。
    4. 在“Select Column”部分,指定包含当前参数数据的列可以指定列号或者列名。注意:列标题默认为第0行(row 0)。
    5. 从“Select next row”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是:Sequential、Random、Unique或者Same Line As。其中每一项的含义文章前面已经讲述,就不再赘述。
    6. 如果选择“Advance row each iteration”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。
    要指定数据库连接或者SQL语句
    1. 选择“Specify SQL Statement”,然后点击“Next”。
    2. 点击“Create”指定一个新的连接字符串。选择数据源的窗口弹出。
    3. 选择已有的数据源,或者点击“New”创建一个新的数据源。向导将提示你穿过创建ODBC数据源的过程。在完成后,连接字符串就会在连接字符串框中显示出来。
    4. 在SQL框中,输入或者粘贴SQL语句。
    5. 点击“Finish”继续SQL语句并导入数据。数据库记录将以data文件的形式显示在参数属性框中。
    6. 在“Select Column”部分中,指定包含当前参数数据的列。你可以指定列号或者列名。
    7. 从“Select next row”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是:Sequential、Random、Unique或者Same Line As。
    8. 如果选择“Advance row each iteration”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。 一、关于参数的定义
    在你录制程序运行的过程中,脚本生成器自动生成由函数组成的用户脚本。函数中参数的值就是在录制过程中输入的实际值。
    例如,你录制了一个Web应用程序的脚本。脚本生成器生成了一个声明,该声明搜索名称为“UNIX”的图书的数据库。
    当你用多个虚拟用户和迭代回放脚本时,也许你不想重复使用相同的值“UNIX”。那么,你就可以用参数来取代这个常量。
    结果就是你可以用指定的数据源的数值来取代参数值。数据源可以是一个文件,也可以是内部产生的变量。
    用参数表示用户的脚本有两个优点:
    ① 可以使脚本的长度变短。
    ② 可以使用不同的数值来测试你的脚本。例如,如果你企图搜索不同名称的图书,你仅仅需要写提交函数一次。在回放的过程中,你可以使用不同的参数值,而不只搜索一个特定名称的值。
    参数化包含以下两项任务:
    ① 在脚本中用参数取代常量值。
    ② 设置参数的属性以及数据源。
    参数化仅可以用于一个函数中的参量。你不能用参数表示非函数参数的字符串。
    另外,不是所有的函数都可以参数化的。
    二、参数的创建
    可以指定名称和类型来创建参数。不存在对脚本中参数个数的限制。
    在Web程序的用户脚本中,你可以使用如下过程在基于文本的脚本视图中创建参数。或者,也可以在基于图标的树形视图中创建参数。
    要创建一个参数:
    1、 将光标定位在要参数化的字符上,点击右键。打开弹出菜单。
    2、 在弹出菜单中,选择“Replace with a Parameter”。选择或者创建参数的对话框弹出。
    3、 在“Parameter name”中输入参数的名称,或者选择一个在参数列表中已经存在的参数。
    4、 在“Parameter type”下拉列表中选择参数类型。
    5、 点击“OK”,关闭该对话框。脚本生成器便会用参数中的值来取代脚本中被参数化的字符,参数用一对“{}”括住。
    注意:在参数化CORBA或者General-Java 用户脚本的时候,必须参数化整个字符串,而不是其中的部分。
    另外注意:除了Web或者WAP,缺省的参数括号对于任何脚本都是 “{}”。你可以在“General Options”对话框中的“Parameterization”标签(Tools>General Options)中定义参数括号种类。
    6、 用同样的参数替换字符的其余情况,选中参数,点击右键,弹出菜单。从弹出的菜单中,选择“Replace More Occurrences”。搜索和替换对话框弹出。
    “Find What”中显示了你企图替换的值。“Replace With”中显示了括号中参数的名称。
    选择适当的检验框来匹配整个字符或者大小写。如果要搜索规则的表达式(.,!,?等等),选中“Regular Expression”检验框,然后点击“Replace”或者“Replace All”。
    注意:小心使用“Replace All”,尤其替换数字字符串的时候。脚本生成器将会替换字符出现的所有情况。
    7、 如果想用以前定义过的参数来替换常量字符串的话,选中该字符串,点击右键,然后选择“Use Existing Parameter”,子菜单“Use Existing Parameters”弹出。
    从子菜单“Use Existing Parameters”选择参数,或者用“Select from Parameter List”来打开参数列表对话框。
    注意:如果用以前定义过的参数来替换常量字符串的话,那么,使用“Parameter List”非常方便。同时,还可以查看和修改该参数的属性。
    8、 对于已经用参数替换过的地方,如果想取回原来的值,那么,就在参数上点击右键,然后选择“Restore Original Value”。
    在Web用户脚本的树形视图中创建参数
    在Web用户脚本的树形视图中创建一个参数的步骤
    1、将光标定位在企图参数化的地方,点击右键,从弹出的菜单中选择“Properties”。则相关的属性对话框打开。
    2、点击在要参数化的参量的旁边的“ABC”形状的图标。“Select or Create Parameter”对话框打开。
    3、在“Parameter name”中输入参数的名称,或者从列表中选择一个已经存在的参数。
    4、在“Parameter type”中输入参数的类型。
    5、点击“OK”关闭该对话框。用户脚本生成器会用参数来替换最初的字符串常量,并用一个表格形状的图标替换“ABC”形状的图标。
    6、要恢复参数化以前的值,点击图标,然后从弹出的菜单中选择“Undo Parameter”,则以前的值便会重现。
    三、定义参数的属性
    创建参数完成后,就可以定义其属性了。参数的属性定义就是定义在脚本执行过程中,参数使用的数据源。
    在Web用户脚本中,你既可以在基于文本的脚本视图中定义参数属性,也可以在基于图标的树形视图中定义参数属性。下面的过程将教你如何在基于本文的脚本视图中定义参数属性。
    定义参数属性步骤:
    1、 在参数上点击右键,有菜单弹出。
    2、 在弹出的菜单中,选择“Parameter Properties”。参数属性对话框打开,显示和当前参数类型相关的属性。
    3、 输入参数的属性值。
    4、 点击“Close”关闭参数属性对话框。
    在Web用户脚本的树形视图中定义参数的属性
    1、 将关标定位在参数上,然后点击右键,选择“Properties”。属性对话框打开。
    2、 点击要定义属性的参数旁边的表格形状按钮,点击右键,选择“Parameter Properties”。参数属性对话框打开,和参数类型相关的属性显示出来。
    3、 输入参数的属性。
    4、 点击“Close”关闭参数属性对话框。
    使用参数列表
    使用参数列表可以在任意时刻查看所有的参数,创建新的参数、删除参数,或者修改已经存在参数的属性。
    要使用参数列表:
    1、 点击参数列表按钮或者用“Vuser>Parameter List”。参数列表对话框打开。
    2、 要创建新的参数,点击“New”按钮。新的参数则被添加在参数树中,该参数有一个临时的名字,你可以给它重新命名,然后回车。
    注意:不要将一个参数命名为“unique”,因为这个名称是用户脚本生成器本身的。
    设置参数的类型和属性,点击“OK”,关闭参数列表对话框。
    注意:用户脚本生成器创建新的参数,但是不会自动用该参数在脚本中替换任意选中的字符串。
    3、 要删除已有的参数,那么,要先从参数树中选择该参数,点击“Delete”,然后确认你的行为即可。
    4、 要修改已有参数,那么,要先从参数树中选择该参数,然后编辑参数的类型和属性。
    四、理解参数的类型
    在你定义参数属性的时候,要指定参数值的数据源。你可以指定下列数据源类型的任何一种:
    Internal Data 虚拟用户内部产生的数据。
    Data Files 存在于文件中的数据。可能是已存在的文件或者是用脚本生成器新创建的。
    User-Defined Functions 调用外部DLL函数生成的数据
    Internal Data包括以下几种:
    1. Date/Time
    Date/Time用当前的日期/时间替换参数。要指定一个Date/Time格式,你可以从菜单列表中选择格式,或者指定你自己的格式。这个格式应该和你脚本中录制的Date/Time格式保持一致。
    2. Group Name
    Group Name 用虚拟用户组名称替换参数。在创建scenario的时候,你可以指定虚拟用户组的名称。当从用户脚本生成器运行脚本的时候,虚拟用户组名称总是None。
    3. Load Generator Name
    Load Generator Name用脚本负载生成器的名称替换参数。负载生成器是虚拟用户在运行的计算机。
    4. Iteration Number
    Iteration Number用当前的迭代数目替换参数。
    5. Random Number
    Random Number用一个随机数替换参数。通过指定最大值和最小值来设置随机数的范围。
    6. Unique Number
    Unique Number用一个唯一的数字来替换参数。你可以指定一个起始数字和一个块的大小。
    7. Vuser ID
    Vuser ID用分配给虚拟用户的ID替换参数,ID是由Loadrunner的控制器在scenario运行时生成的。如果你从脚本生成器运行脚本的话,虚拟用户的ID总是-1。
    五、数据文件
    数据文件包含着脚本执行过程中虚拟用户访问的数据。局部和全局文件中都可以存储数据。可以指定现有的ASCII文件、用脚本生成器创建一个新的文件或者引入一个数据库。在参数有很多已知值的时候数据文件非常有用。
    数据文件中的数据是以表的形式存储的。一个文件中可以包含很多参数值。每一列包含一个参数的数据。列之间用分隔符隔开,比如说,用逗号。
    对数据文件设置参数属性
    如果使用文件作为参数的数据源,必须指定以下内容:
    1. 文件的名称和位置
    2. 包含数据的列
    3. 文件格式,包括列的分隔符
    4. 更新方法
    如果参数的类型是“File”,打开参数属性(Parameter Properties)对话框,设置文件属性如下:
    1. 在“File path”中输入文件的位置,或者点击“Browse”指定一个已有文件的位置。缺省情况下,所有新的数据文件名都是“parameter_name.dat”,注意,已有的数据文件的后缀必须是.dat。
    2. 点击“Edit”。记事本打开,里面第一行是参数的名称,第二行是参数的初始值。使用诸如逗号之类的分隔符将列隔开。对于每一新的表行开始一行新的数据。
    注意:在没有启动记事本的情况下如果想添加列,就在参数属性对话框中点击“Add Col”,那么“Add new column”对话框就会弹出。输入新列的名称,点击“OK”。脚本生成器就会添加该列到表中,并显示该列的初始值。
    3. 在“Select Column”部分,指明包含当前参数数据的列。你可以指定列名或者列号。列号是包含你所需要数据的列的索引。列名显示在每列的第一行(row 0)。
    4. 在“Column delimiter”中输入列分隔符,你可以指定逗号、空格符等等。
    5. 在“First data line”中,在脚本执行的时候选择第一行数据使用。列标题是第0行。若从列标题后面的第一行开始的话,那就在“First data line”中输入1。如果没有列标题,就输入0。
    6. 在“Select next row”中输入更新方法,以说明虚拟用户在脚本执行的过程中如何选择表中的数据。方法可以是:连续的、随机的、唯一的、或者与其它参数表的相同行。
    7. 选中“Advance row each iteration”表示虚拟用户在每次迭代都使用新的一行数据而不是所有的迭代都使用相同的数据。
    从文件中更新参数值
    若使用文件中的数值,脚本生成器会要求你指定给参数分配数值给的方法。可用的方法有:
    1. 顺序(Sequential):该方法顺序地给虚拟用户分配参数值。如果正在运行的虚拟用户访问数据表的时候,它会取到下一行中可用的数据。
    2. 随机(Random):该方法在每次迭代的时候会从数据表中取随机数
    3. 使用种子取随机顺序(Use Random Sequence with Seed):如果从Loadrunner的控制器来运行scenario,你可以指定一个种子数值用于随机顺序。每一个种子数值在测试执行的时候代表了一个随机数的顺序。无论你何时使用这个种子数值,在scenario中同样的数据顺序就被分配给虚拟用户。如果在测试执行的时候发现了一个问题并且企图使用同样的随机数序列来重复测试,那么,你就可以启动这个功能(可选项)。
    4. 唯一(Unique):Unique方法分配一个唯一的有顺序的值给每个虚拟用户的参数。
    5. 与以前定义的参数取同一行(Same Line As <parameter>):该方法从和以前定义过的参数中的同样的一行分配数据。你必须指定包含有该数据的列。在下拉列表中会出现定义过的所有参数列表。注意:至少其中的一个参数必须是Sequential、Random或者Unique。
    如果数据表中有三列,三个参数定义在列表中:id1,name1和title1,如下:。
    ID Name Title
    132 Kim Manager
    187 Cassie Engineer
    189 Jane VP
    对于参数id1,你可以指示虚拟用户使用Random方法,而为参数name1和title1就可以指定方法“Same Line as id1”。所以,一旦ID“132”被使用,那么,姓名(Name)“Kim”和职位(Title)“Manager”同时被使用。
    六、从已存在的数据库中导入数据
    Loadrunner允许你利用参数化从已经存在的数据库中导入数据。可以使用下列两种方式之一:
    1. 使用Microsoft Query(要求在系统上先安装MS Query)。
    2. 指定数据库连接字符串和SQL语句。
    用户脚本生成器在从数据库中导入数据的过程中提供了一个向导。在向导中,你指明如何导入数据-通过MS Query创建查询语句或者直接书写SQL语句。在导入数据以后,以.dat为后缀并作为正规的参数文件保存。
    要开始导入数据库中数据的过程,在参数属性对话框中点击“Data Wizard”,则,数据库查询向导弹出。
    要创建新的查询
    1. 选择“Create new query”。如果需要MS Query的帮助,选择“Show me how to use Microsoft Query”,然后点击“Finish”。
    如果你还没有安装Microsoft Query,Loadrunner会提示你这个功能不可用。在进行之前,从Microsoft Office中安装MS Query。
    2. 在Microsoft Query中遵循以下步骤,导入期望的表和列。
    3. 在完成数据的导入后,选择“Exit and return to Virtual User Generator”,然后点击“Finish”。在参数属性对话框中数据库记录以data文件的形式显示出来。
    要在MS Query中编辑并查看数据,选择“View data or edit in Microsoft Query”。若要结束,则选择“File>Exit and return to Virtual User Generator”返回到脚本生成器。
    4. 在“Select Column”部分,指定包含当前参数数据的列可以指定列号或者列名。注意:列标题默认为第0行(row 0)。
    5. 从“Select next row”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是:Sequential、Random、Unique或者Same Line As。其中每一项的含义文章前面已经讲述,就不再赘述。
    6. 如果选择“Advance row each iteration”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。
    要指定数据库连接或者SQL语句
    1. 选择“Specify SQL Statement”,然后点击“Next”。
    2. 点击“Create”指定一个新的连接字符串。选择数据源的窗口弹出。
    3. 选择已有的数据源,或者点击“New”创建一个新的数据源。向导将提示你穿过创建ODBC数据源的过程。在完成后,连接字符串就会在连接字符串框中显示出来。
    4. 在SQL框中,输入或者粘贴SQL语句。
    5. 点击“Finish”继续SQL语句并导入数据。数据库记录将以data文件的形式显示在参数属性框中。
    6. 在“Select Column”部分中,指定包含当前参数数据的列。你可以指定列号或者列名。
    7. 从“Select next row”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是:Sequential、Random、Unique或者Same Line As。
    8. 如果选择“Advance row each iteration”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。

231/212>
Open Toolbar