51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 6304|回复: 3
打印 上一主题 下一主题

[原创] 自动化友好、干净停止loadrunner运行场景的源代码

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2008-8-1 23:18:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近针对loadrunner做功能扩展,其中一个环节是:尽力正常点击stop停止,如经过处理无法停止,则干净终止loadrunner进程。

  loadrunner手册有命令行方式启动wlrun.exe进程的方式,但没有停止wlrun.exe的方式。本方法用win32实现友好停止Loadrunner场景。

  窗口层次关系可以用spy++察看 .

  测试程序的方法,启动一个loadrunner运行场景。

#include <stdlib.h>
#include <stdio.h>
#include  <time.h>
#include  <errno.h>
#include <locale.h>
#include <windows.h>
#include <vdmdbg.h>


typedef struct
   {
      DWORD   dwID ;
      DWORD   dwThread ;
   } TERMINFO ;

  BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;


DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )
   {
      HANDLE   hProc ;
      DWORD   dwRet ;

      // If we can't open the process with PROCESS_TERMINATE rights,
      // then we give up immediately.
      hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,
         dwPID);

      if(hProc == NULL)
      {
         return FALSE ;
      }

      // TerminateAppEnum() posts WM_CLOSE to all windows whose PID
      // matches your process's.
      EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;

      // Wait on the handle. If it signals, great. If it times out,
      // then you kill it.
      if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0)
         dwRet=(TerminateProcess(hProc,0)?TRUE:FALSE);
      else
         dwRet = TRUE ;

      CloseHandle(hProc) ;

      return dwRet ;
   }


BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
  DWORD dwID ;

  GetWindowThreadProcessId(hwnd, &dwID) ;

  if(dwID == (DWORD)lParam)
  {
     PostMessage(hwnd, WM_CLOSE, 0, 0) ;
  }

  return TRUE ;
}

//MyEnumWindow 函数本身只能枚举最top-level的窗口。
//嵌套的窗口自己枚举

//这里用spy++观察层次结构
//模拟用户鼠标操作停止loadrunner的过程
BOOL   CALLBACK    MyEnumWindow(HWND   hWnd,   LPARAM   lParam)
{
   char    sz_text[MAX_PATH]={0};  
   int  len =0;
   char  * p_title = NULL;
   int  ret;
   HWND child_hWnd=NULL,dialog_hWnd=NULL,next_hWnd=NULL;
   int  i=0;
   BOOL isFound = FALSE;
   int try_time=10;
   WINDOWINFO  winInfo;
   DWORD dwID ;
   p_title=(char*)lParam;

   len= GetWindowText(hWnd,   sz_text,   sizeof(sz_text)/sizeof(sz_text[0]));   
   if (strstr(sz_text,"LoadRunner"))
        printf("%s\r\n",sz_text);  
   child_hWnd = hWnd;
   if(strstr(sz_text,p_title))   
   {   
      
   while(1)
   {
    //获取子窗口
    child_hWnd=GetWindow(child_hWnd, GW_CHILD);
    //恶意关闭loadrunner时,窗口是否为存在?防止死循环。
    if(child_hWnd!=NULL)
    {
     len= GetWindowText(child_hWnd, sz_text, sizeof(sz_text)/sizeof(sz_text[0]));      
     if (!strcmp(sz_text,"&Start Scenario"))
     {
     //获取兄弟窗口
     next_hWnd=GetWindow(child_hWnd, GW_HWNDNEXT);
     len= GetWindowText(next_hWnd,sz_text,   sizeof(sz_text)/sizeof(sz_text[0]));
     if (!strcmp(sz_text,"S&top") )
     {
      //找到停止的窗口
      isFound =TRUE;
      break;
     }   
     }
    }
    else   //child_hWnd!=NULL
    {
    break;
    }
   } //while

   
   if (FALSE ==isFound )
   {
    //失败退出
    printf("not found S&top!\r\n");
    return TRUE;
   }

   //尝试投递try_time次。
   //for(i=0;i < try_time; i++)
   while(1)
   {

    //SendMessage(next_hWnd,  BM_CLICK,0,  0);
    PostMessage(next_hWnd,  BM_CLICK,0,  0); // 这里不能用SendMessage,否则阻塞进程
    dialog_hWnd  = FindWindow("#32770", "LoadRunner Controller");
   
    if (!dialog_hWnd)   
    {
     printf("Find dialog error.  ret=%d\r\n",GetLastError());
    }
    else  
    {      
     //if  (IsWindowVisible(dialog_hWnd))
     //{
      len= GetWindowText(dialog_hWnd,  sz_text, sizeof(sz_text)/sizeof(sz_text[0]));
      printf("GetWindowText  return %s\r\n",sz_text);           
      //查找对话框上按纽
      child_hWnd  =  FindWindowEx(dialog_hWnd,0,"Button","确定");
      if (!child_hWnd)
      {
       printf("确定 button  ret=%d\r\n",GetLastError());
       continue;
      }

      SendMessage(child_hWnd, BM_CLICK,0,  0);
      ret = GetLastError();
      if (ret)
      {
       printf("button  error. ret=%d\r\n",ret);
      }
      else
      {
        printf("正常停止loadrunner!\r\n");
      }
       //经过如上处理后
      printf("destroywindows\r\n");
       Sleep(10);
       //强行关闭loadrunner相关进程
         GetWindowThreadProcessId(hWnd, &dwID) ;
      TerminateApp(dwID,10);
      return   FALSE;   
     //}
    } //(!prev_hWnd)
   }//for
   }  

   return   TRUE;   
}
int stop_loadrunner()
{

  char    sz_title[]="Mercury LoadRunner Controller ";
  //  char    sz_title[]="S&top";
  if (EnumWindows(MyEnumWindow,(long) sz_title) )
    printf("failed,errno=%d",GetLastError());

}


void main()

{

stop_loadrunner();

}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
发表于 2008-8-2 09:02:50 | 只看该作者
哥们你怎么会想到发这么个帖子呢?你还不如写个自动关机的脚本来的比较省电!
回复 支持 反对

使用道具 举报

该用户从未签到

3#
 楼主| 发表于 2008-8-2 17:51:58 | 只看该作者
呵呵,楼上的朋友太幽默了

我说过了,我针对loadrunner做外围的扩展的,需要自动化地启动、友好停止LR。 这2环节只是整个扩展的一小步。

写程序肯定有用意的,哪怕是实现一个很小的代码片段,对不
回复 支持 反对

使用道具 举报

该用户从未签到

4#
 楼主| 发表于 2008-8-3 23:39:40 | 只看该作者
阿里巴巴网站未来朝平台化,产品化方向迈进,编写测试程序来测试程序的机会将会更多。
故对测试工程师编程能力提出更高要求
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-20 19:23 , Processed in 0.076483 second(s), 27 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表