-
开发自动化脚步录制器
2013-12-16 18:47:52
原理:
1. 利用BHO(Browser Helper Object),在页面内装入event监听事件,当然动态装入事件,可以多种方式,用pwatir也可以。
2. 监听事件的处理:在页面内所有元素上装一遍事件来监听,不靠谱, 这里用到了JS事件冒泡原理,因为事件会向上传递,所以只需简单的在最上次document装入监听事件。
document.attachEvent('onmouseover', myonmouseover);
document.attachEvent('onclick', myonclick);
function myonclick(event){
var element = event.srcElement;//就是被点击的元素
//element.id, name, tagName, value ,
//className, innerText
//可根据以上元素来定位元素
}
Event参考:http://msdn.microsoft.com/en-us/library/ms535863(v=VS.85).aspx
Element参考: http://msdn.microsoft.com/en-us/library/ms533054(v=VS.85).aspx
安装: (win7权限问题,注册不成功,用管理员权限运行)
regsvr32 D:\CBURecordBHO.dll
卸载:
regsvr32 D:\CBURecordBHO.dll /u
使用:(IE8上可用,IE9上有问题)
1. 按F12打开开发人员工具
2. 操作页面即可录制,按住CTRL,鼠标移到元素上即生成check
缺点:
1.因直接利用window.console输出,因此不支持IE6, ActiveXObject("Scripting.FileSystemObject")支持本地输出,但需要降低IE安全级别。
2. 不是pwatir完整解决方案,只是录制环节。
优点:
1. 纯JS生成录制脚步,跟Selenium一样,可根据需要生成不同语言的脚本
2.录制反向定位可以变成回放,当然写出Selenium core的js脚本考验能力。
-
windows服务程序开发--电源计划自动切换
2012-01-13 10:30:07
windows服务程序开发---电源计划自动切换
windows服务程序(Windows Service)就像系统的一些服务一样,能够自动地启动,并执行相应的操作; 而且因为服务程序的在层次上和一般的应用程序不同,其能够在系统启动时就自动地运行,而不像一般的 应用程序那样一定要在登陆后才能运行,可以暂停和重新启动而且不显示任何用户界面。这使服务非常适合在服务器上使用。
平台环境:
操作系统:windows7 企业版
编译环境:VS2010旗舰版
.Framework:4.0
【成品展示】
运行services.msc,启动服务控制界面
作用: 根据电源状态,自动切换电源计划模式( 交流电就切换成高性能模式, 电池就切换成节能模式)
【使用的winAPI】
#根据注册表中的电源Scheme的GUID设置电源计划
GUID: 即Globally Unique Identifier(全球唯一标识符)
DWORD WINAPI PowerSetActiveScheme(
__in_opt HKEY UserRootPowerKey,
__in const GUID *SchemeGuid
);
http://msdn.microsoft.com/en-us/library/windows/desktop/aa372758(v=vs.85).aspx
#枚举电源使用方案
DWORD WINAPI PowerEnumerate(
__in_opt HKEY RootPowerKey,
__in_opt const GUID *SchemeGuid,
__in_opt const GUID *SubGroupOfPowerSettingsGuid,
__in POWER_DATA_ACCESSOR AccessFlags,
__in ULONG Index,
__out_opt UCHAR *Buffer,
__inout DWORD *BufferSize
);
http://msdn.microsoft.com/en-us/library/windows/desktop/aa372730(v=vs.85).aspx
#检索指定的电源计划的友好名称(节能,高性能,平衡)
DWORD WINAPI PowerReadFriendlyName(
__in_opt HKEY RootPowerKey,
__in_opt const GUID *SchemeGuid,
__in_opt const GUID *SubGroupOfPowerSettingsGuid,
__in_opt const GUID *PowerSettingGuid,
__out_opt PUCHAR Buffer,
__inout LPDWORD BufferSize
);
http://msdn.microsoft.com/en-us/library/windows/desktop/aa372740(v=vs.85).aspx
#检索系统的电源状态
BOOL WINAPI GetSystemPowerStatus(
__out LPSYSTEM_POWER_STATUS lpSystemPowerStatus
);
http://msdn.microsoft.com/en-us/library/windows/desktop/aa372693(v=vs.85).aspx
这四个电源管理API,已能满足我们serviceDemo的需求,
但还缺电源状态变更事件,
public: static event PowerModeChangedEventHandler^ PowerModeChanged {
void add (PowerModeChangedEventHandler^ value);
void remove (PowerModeChangedEventHandler^ value);
}
http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.powermodechanged.aspx
[HostProtectionAttribute(SecurityAction::LinkDemand, MayLeakOnAbort = true)]
public delegate void PowerModeChangedEventHandler(
Object^ sender,
PowerModeChangedEventArgs^ e
)
http://msdn.microsoft.com/en-us/library/microsoft.win32.powermodechangedeventhandler.aspx
事件处理句柄函数中重要参数PowerModeChangedEventArgs
http://msdn.microsoft.com/en-us/library/microsoft.win32.powermodechangedeventargs.aspx
准备的差不多了,开始组装
[注册事件code]
#include <PowrProf.h>
#pragma comment(lib,"powrprof.lib")
using namespace System;
SystemEvents::PowerModeChanged += gcnew ::PowerModeChangedEventHandler(SystemEvents_PowerModeChanged/*自定义的事件处理函数*/);
[自定义事件处理函数]
void SystemEvents_PowerModeChanged(Object^ sender, PowerModeChangedEventArgs ^ e)
{
if(e->Mode==PowerModes::StatusChange){ //供电模式变更
SYSTEM_POWER_STATUS lpPwrStatus; //存储电源状态
GetSystemPowerStatus(&lpPwrStatus); //获取电源状态
GUID GuidActiveSheme; //存储电源计划GUID 即Globally Unique Identifier(全球唯一标识符)
if(lpPwrStatus.ACLineStatus==0){ //非AC(交流电), 也就是电池模式
//电池模式,改成节能模式
FindPowerSheme("节能", &GuidActiveSheme); //查“节能”电源计划的GUID
PowerSetActiveScheme(NULL, &GuidActiveSheme); //直接调用API 切换电源计划 //printf("转为节能模式\n");
//printf("电池余量=%d\n", lpPwrStatus.BatteryLifePercent);
}else if(lpPwrStatus.ACLineStatus==1){ //AC(交流电)模式
//交流电模式,改成高效模式
FindPowerSheme("高性能", &GuidActiveSheme); //查“高性能”电源计划的GUID
PowerSetActiveScheme(NULL, &GuidActiveSheme); //直接调用API 切换电源计划 //printf("转为 高性能 模式\n");
// printf("电池余量=%d\n", lpPwrStatus.BatteryLifePercent);
}
}
}
上面的事件函数中使用了一个根据电源计划友好名称(中文名称)查电源计划GUID的方法
[FindPowerSheme实现]
//pShemeName: 输入电源计划友好名称
//pGUID: 输出电源计划GUID
bool FindPowerSheme(LPSTR pShemeName, GUID* pGUID)
{
GUID SchemeGuid;
ULONG index = 0;
DWORD BufferSize = sizeof(GUID);
UCHAR pSchemeBuf[2*MAX_PATH];
DWORD dwSchemeSize=2*MAX_PATH;
CHAR szSchemeName[2*MAX_PATH];
if(!pGUID || !pShemeName) false;
//遍历电源计划
while(ERROR_SUCCESS == PowerEnumerate(NULL, NULL, NULL, ACCESS_SCHEME, index, (PUCHAR)&SchemeGuid, &BufferSize))
{
//根据电源计划guid获取电源计划友好名称
PowerReadFriendlyName(NULL, (GUID*)&SchemeGuid, NULL, NULL, (PUCHAR)pSchemeBuf, &dwSchemeSize);
//unicode字符串到一个多字节字符串
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pSchemeBuf, -1, (LPSTR)szSchemeName, MAX_PATH, NULL, NULL);
if(strcmp(szSchemeName, pShemeName) == 0) //找到输入电源计划友好名称,返回
{
memcpy(pGUID, &SchemeGuid, sizeof(GUID));
//printf("find ok\n");
return true;
}
index++;
}
return false;
}
关于电源管理的所有代码,都已列出
a.编译,运行
b.插入拔出电源测试一下,会自动切换电源计划
如果是作为普通windows应用程序, 那到此已经完工,
但我们是要做成windows服务程序,因此需后续工作。
//==================[windows服务程序]===================================================
ATL,Active Template Library活动模板库,是一种微软程序库,
支持利用C++语言编写ASP代码以及其它ActiveX程序。
通过活动模板库,可以建立COM组件,然后通过ASP页面中的脚本对COM对象进行调用。
这种COM组件可以包含属性页、对话框等等控件。
利用ATL来创建windows服务程序是一种简单的方法,
只用来创建服务程序,不需要COM支持。
【创建ATL windows服务步骤】
a. 新建工程, 选择visual C++里ATL模板创建工程
b. ATL设置向导中的应用程序类型选择服务(ExE)
oK, 这里windows服务程序的框架已经自动生成好了,
但是这个空框架,是启动不起来的,上面介绍了,ATL主要是用来作com组件开发的,
而这个空框架是来做windows服务程序,没加上COM的初始化工作,所有写代码前的
第一步 在stdafx.h中加上
#define _ATL_NO_COM_SUPPORT //不需要COM支持
第二步 添加服务程序
这里重载CServiceDemoModule::run 方法
run方法可以参考父类CAtlServiceModuleT中的run方法,在atlbase.h有定义
HANDLE event;
HRESULT Run(int nShowCmd = SW_HIDE) throw()
{
HRESULT hr = S_OK;
hr = __super::PreMessageLoop(nShowCmd);
if (hr == S_OK)
{
if (m_bService)
{
//可以在这里启动线程,或者什么其他东西来做自己的工作的啦
event = CreateEvent(NULL, FALSE, FALSE, NULL); //这里初始化无事件状态,否则调用ReSetEvent函数,置事件为无状态
//HANDLE hThread = CreateThread( NULL, 0, ThreadFunc, NULL, 0, NULL); //这里没有新开线程来处理
LogEvent(_T("CServiceDemoModule 的服务启动。。。。。。 "));
SetServiceStatus(SERVICE_RUNNING);
LogEvent (_T("PowerModeChanged start........."));
//注册电源状态变更事件
SystemEvents::PowerModeChanged += gcnew ::PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
::WaitForSingleObject(event,INFINITE); //由于没在新开线程中处理,这个阻塞一定不能落下
LogEvent (_T("PowerModeChanged stop........."));
}
//进入消息循环,不停的处理消息,可能最后分发到Handler去处理,调用了OnShutdown等函数的。
__super::RunMessageLoop();
}
if (SUCCEEDED(hr))
{
hr = __super::PostMessageLoop();
}
return hr;
}
// 重写,服务退出处理
void OnStop() throw()
{
SetEvent(event); //设置有事件状态, 使阻塞函数WaitForSingleObject可以退出
LogEvent(_T("CServiceDemoModule退出!!!! "));
SetServiceStatus(SERVICE_STOP_PENDING);
PostThreadMessage(m_dwThreadID, WM_QUIT, 0, 0);
}
LogEvent 的输出日志,可以通过eventvwr.msc 事件查看器,浏览
到此所有代码完成,但编译时会有错误,需要公共语言运行时(/clr)支持
也就是net.Framework支持
Alt+F7 打开项目属性配置,在【配置属性】的【常规】栏目中选择【公共语言运行时(/clr)支持】
重新编译通过。
第三步 注册windows服务程序
a. 进入编译输出目录(如 E:\code\vc2010\ServiceDemo\Debug)
b. 执行ServiceDemo.exe /service 注册服务 (ServiceDemo.exe /UnRegServer 注销服务)
c. 执行services.msc,打开服务管理窗口,就可以找到ServiceDemo服务了,然后启动服务
本来应该已是全部完成了,但是拔出电源测试一下,没反应,原来
只有在消息泵运行时,才会引发此事件。 在 Windows 服务中,除非使用隐藏窗体或者手动启动消息泵,否则不会引发此事件。 有关演示如何在 Windows 服务中使用隐藏窗体来处理系统事件的代码示例,请参见 SystemEvents 类
http://msdn.microsoft.com/zh-cn/express/microsoft.win32.systemevents.powermodechanged(en-us,VS.100).aspx
所有还得再加一步
最后一步: ServiceDemo服务的属性中增加【允许与桌面交互】
重新启动服务,能正常工作, Demo结束!!! -
自动化测试中的图片相似度
2012-01-10 09:46:52
c++ opencv VS python PIL VS java BufferedImage//=======================opencv=============================
基本介绍:
OpenCV的全称是:Open Source Computer Vision Library 。OpenCV于1999年由Intel建立,现在由Willow Garage提供支持。OpenCV是一个基于BSD许可证授权(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法,最新版本是2.3。
应用领域:
1、人机互动
2、物体识别
3、图象分割
4、人脸识别
5、动作识别
6、运动跟踪
7、机器人
opencv直方图比较:
相关系数:
卡方:
交集:
巴氏距离:
相似度的源码:
/*
引入opencv
在项目属性的
头文件目录和库文件目录
分别加上OpenCV的头和库目录如
包含目录:
E:\code\vc2010\OpenCV2.2\include\opencv
E:\code\vc2010\OpenCV2.2\include\
库目录:
E:\code\vc2010\OpenCV2.2\lib
*/
#include <cv.h>
#include <highgui.h>
using namespace cv;
//直方图尺寸
int HistogramBins = 256;
float Range1[]={0,255};
float *HistogramRange=Range1;
//两个比较图形对象
IplImage *Image1=cvLoadImage("E:\\code\\python\\o_1.JPG",0);
IplImage *Image2=cvLoadImage("E:\\code\\python\\o_2.JPG",0);
//两个直方图对象
CvHistogram *Histogram1=cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, &HistogramRange);
CvHistogram *Histogram2=cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, &HistogramRange);
//直方图
cvCalcHist(&Image1,Histogram1);
cvCalcHist(&Image2,Histogram2);
//归一化直方图
cvNormalizeHist(Histogram1,1);
cvNormalizeHist(Histogram2,1);
//相似度比较方法:
printf(“相关系数: %.4f\n",cvCompareHist(Histogram1,Histogram2,CV_COMP_CORREL));
printf("卡方 : %.4f\n",cvCompareHist(Histogram1,Histogram2,CV_COMP_CHISQR));
printf("交集 : %.4f\n",cvCompareHist(Histogram1,Histogram2,CV_COMP_INTERSECT));
printf("巴氏距离 : %.4f\n",cvCompareHist(Histogram1,Histogram2,CV_COMP_BHATTACHARYYA));
/*
接口参考
http://fsa.ia.ac.cn/opencv-doc-cn/opencv-doc-cn-0.9.7/ref/opencvref_cv.cn.htm
*/
//=======================python PIL=============================
实现最简单,缺点是无论图片大小,采样点固定为768点, 看了pil的C源码库,写死在代码中,
不过pil切割图片简单,大图可以切小块后,再比较
#导入pil库
import Image
#规格化图片方法
def make_regalur_image(img, size = (256, 256)):
return img.resize(size).convert('RGB')
#相似度计算方法
def hist_similar(lh, rh):
assert len(lh) == len(rh)
return sum(1 - (0 if l == r else float(abs(l - r))/max(l, r)) for l, r in zip(lh, rh))/len(lh)
#加载2张图片
img1=Image.open("E:\\code\\python\\o_1.JPG")
img2=Image.open("E:\\code\\python\\o_2.JPG")
#规格化图片
img1=make_regalur_image(img1)
img2=make_regalur_image(img2)
#计算相似度
ret=hist_similar(img1.histogram(), img2.histogram())
print "similar=",ret
//=======================java=============================
使用BufferedImage, 是用跟python计算相似度的算法(或者用opencv的巴氏距离,相关系数),
或者指定区域,指定采样点数
BufferedImage image1 = ImageIO.read(new File("E:\\code\\python\\o_1.JPG"));
BufferedImage image2 = ImageIO.read(new File("E:\\code\\python\\o_2.JPG"));
int[] img1RGB=image1.getRGB(0, 0, image1.getWidth(), image1.getHeight(), null, 0, image1.getWidth());
int[] img2RGB=image2.getRGB(0, 0, image2.getWidth(), image2.getHeight(), null, 0, image2.getWidth());
//相似度计算公式
public double similar(int[] img1RGB, int[] img2RGB){
int nSize = img1RGB.length < img2RGB.length ? img1RGB.length : img2RGB.length;
if(nSize==0) return 0;
double nSum=0.0;
for(int i=0; i<nSize; i++){
nSum = nSum + (1 - Math.abs((double)(img1RGB-img2RGB)) / Math.abs(img1RGB < img2RGB ? img1RGB : img2RGB));
}
return nSum / nSize;
}
//计算相似度
double rt = similar(img1RGB, img2RGB);
System.out.println("rt="+rt); -
MySQL vs2010编译调试和命令扩展
2012-01-10 09:41:02
最近Mysql数据库应用越来越广泛,所以,决定学学Mysql,把Mysql的源码下载了,希望能有利于对它的学习,看到淘宝测试人员能扩展mysql命令,自己决定也试一下
这里记录一下windows平台下编译Mysql的过程,以及命令扩展的过程,与大家分享一下。
平台环境:
操作系统:windows7 企业版
编译环境:VS2010旗舰版
辅助工具:CMake2.8【windows版本】
Mysql版本:mysql-5.1.60
Bison版本:bison-2.4.1
编译过程:1. 下载mysql-5.1.60源码,解压到D:\mysql2. 使用CMake2.8生成vs2010工程(源码自带的脚本只支持到vs2008)
3. 打开D:\mysql\sql\sql_local.cc文件,另存为UTF-8格式(带BOM头),覆盖原文件4. 打开D:\mysql\sql\mysqld.cc, 4352行:DBUG_ASSERT(0);改为DBUG_ASSERT(1);或者注释掉整个IF语句5. 将D:\mysql\win\data目录拷贝到D:\mysql\sql下6. 用vs2010打开D:\mysql\MySql.sln 编译全部
调试过程1. 进入D:\mysql\sql\Debug\, 输入命令 mysqld --debug --standalone, 这时3306端口开启侦听(用netstat -anp tcp)2. 在VS2010中附加进程调试中选择“mysqld.exe”3. 在D:\mysql\sql\sql_show.cc 的make_db_list方法中设一个断点4. 进入 D:\mysql\client\Debug, 输入命令 mysql -u root -p ,进入mysql命令行客户端5. 在mysql命令行客户端,输入命令show databases;就会跳到vs2010中设定的断点处6. 进入D:\mysql\client\Debug, 输入命令 mysqladmin shutdown -u root -p 关闭mysql服务现在有了源码,而且可以方便的在vs2010设定断点跟踪,可以好好学习了
命令扩展过程主要参考:《Expert MySQL》第8章第3节现有SQL不能满足需要,自定义函数也解决不了,可以考虑新增SQL命令。通过修改源代码的方法,扩展MySQL功能,比较复杂和繁琐。1. 修改解析器(D:\mysql\sql\sql_yacc.yy)2. 添加命令路由(D:\mysql\sql\sql_parse.cc)3. 添加命令实现函数代码(D:\mysql\sql\sql_show.cc)具体步骤:1.修改解析器1.1 在lex.h 增加命令符号,在符号表数组static SYMBOL symbols[] = {}中增加,自定义符号DISK_USAGE{ "DISK", SYM(DISK_SYM)},
{ "DISK_USAGE", SYM(DISK_USAGE_SYM)}, /*guoping.gugp add*/
{ "DISTINCT", SYM(DISTINCT)},1.2 在sql_lex.h 增加助记符,命令路由时用在命令助记符枚举表enum enum_sql_command{}中,增加助记符SQLCOM_SHOW_DISK_USAGESQLCOM_SHOW_COLUMN_TYPES, SQLCOM_SHOW_STORAGE_ENGINES, SQLCOM_SHOW_PRIVILEGES,
SQLCOM_SHOW_DISK_USAGE, /*guoping.gugp add*/
SQLCOM_HELP, SQLCOM_CREATE_USER, SQLCOM_DROP_USER, SQLCOM_RENAME_USER,1.3 把新增符号添加到解析器(把1.1和1.2的符号关联起来)在sql_yacc.yy中增加符号%token DISK_SYM
%token DISK_USAGE_SYM /* guoping.gugp add */
%token DISTINCT /* SQL-2003-R */在sql_yacc.yy中的show:增加符号处理, 注意竖线不能缺/* guoping.gugp add */
SHOW DISK_USAGE_SYM
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_SHOW_DISK_USAGE;
}|
SHOW{2. 添加命令路由2.1 在mysql_priv.h增加新命令执行函数的申明bool mysqld_show_authors(THD *thd);
bool show_disk_usage_command(THD *thd); /*guoping.gugp add*/
bool mysqld_show_contributors(THD *thd);2.2 在sql_parse.cc的命令路由中增加新命令路由(1.3中解析器关联到新命令的执行函数show_disk_usage_command)case SQLCOM_SHOW_AUTHORS:
res= mysqld_show_authors(thd);
break;
case SQLCOM_SHOW_DISK_USAGE: /*guoping.gugp add*/
res= show_disk_usage_command(thd);
break;
case SQLCOM_SHOW_CONTRIBUTORS:
res= mysqld_show_contributors(thd);
break;3. 添加命令实现函数代码在sql_show.cc中增加命令实现函数/* guoping.gugp add begin */
bool show_disk_usage_command(THD *thd)
{
List<Item> field_list;
Protocol *protocol= thd->protocol;
DBUG_ENTER("show_disk_usage");/* send fields */
field_list.push_back(new Item_empty_string("CBU_Database",50));
field_list.push_back(new Item_empty_string("CBU_Size (kb)",30));if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);/* send test data */
protocol->prepare_for_resend();
protocol->store("B2B_CBU_ROW", system_charset_info);
protocol->store("1024", system_charset_info);
if(protocol->write())
DBUG_RETURN(TRUE);my_eof(thd);DBUG_RETURN(FALSE);
}/* guoping.gugp add end */4. 重新编译
4.1 在windows编译,会有符号未定义错误,需在sql_yacc.cc 中增加定义
/* Substitute the variable and function names. */
#define yyparse MYSQLparse
#define yylex MYSQLlex
#define yyerror MYSQLerror
#define yylval MYSQLlval
#define yychar MYSQLchar
#define yydebug MYSQLdebug
#define yynerrs MYSQLnerrs
4.2 使用bison,重新生成解析器代码
bison -y -d sql_yacc.yy
会生成两个新文件y.tab.c 和y.tab.h,分别替换掉之前原有的sql_yacc.cc和sql_yacc.h
4.3 大功告成,重新编译mysql
启动mysql服务器 D:\mysql\sql\Debug\mysqld --debug --standalone
启动mysql客户端 D:\mysql\client\Debug\mysql -u root
执行新命令 show DISK_USAGE
-
loadrunner扩展之环境准备 vc2008+LR8.1
2010-10-29 16:21:41
工具准备阶段: loadrunner, VC2008
1. Microsoft Visual Studio2008 (vc9 vc2008)
D:\Program Files\Microsoft Visual Studio 9.0\
vc2008个头大,安装完1.6G左右,考虑到我可怜的C盘,还是挪窝
2. Mercury Loadrunner (LR8.1)
C:\Program Files\Mercury Interactive\Mercury LoadRunner
默认路径,LR8.1个头也不小,600M左右
3. 编译环境设置
3.1. 菜单文件-->新建-->项目 或者快捷键 ctrl+shift+N (看不清,点图放大)
3.2. 确定后,再点下一步, 不要直接点完成哦(看不清,点图放大)
3.3. 完成的,最终成果(看不清,点图放大):
4. 洗洗手,开始上把,先来个简单的
4.1 编辑lr_dll_test.h 头文件
在自动生成的fnlr_dll_test函数声明前,加上extern "C"
//自动生成的
//LR_DLL_TEST_API int fnlr_dll_test(void);
//修改后的, 因为LR只支持C,不支持C++,所有加上extern "C",
//告诉编译器,用C语法编译器
extern "C" LR_DLL_TEST_API int fnlr_dll_test(void);
4.2 编辑 lr_dll_test.cpp
//根据兴趣修改自动导出示例
// 这是导出函数的一个示例。
LR_DLL_TEST_API int fnlr_dll_test(void)
{
int a = 50;
int b = 200;
return a+b;
}
4.3 大功告成(简单吧,其实只加了一句extern "C" ),开始编译
菜单 生成->生成解决方案 或 快捷键 F7, 在lr_dll_test\Debug
目录下生成lr_dll_test.dll。
5. LR调用DLL方法,有两种
5.1一种是通过lr_load_dll函数,
5.1.1直接指定路径lr_load_dll("D:\\vc2008\\lr_dll_test\\Debug\\dll_test.dll");
注意是两反斜杠
5.1.2 拷贝DLL到LR脚本目录,或者LR安装目录,直接lr_load_dll("dll_test.dll")
C:\Program Files\Mercury Interactive\Mercury LoadRunner\bin
5.2第二种是全局调用,VUGen启动时自动加载
修改,LR安装目录,dat子目录下的mdrv.dat文件,[lrun] 字段,在末尾添加
C:\Program Files\Mercury Interactive\Mercury LoadRunner\dat\mdrv.dat
[lrun]
ExtPriorityType=communication
WINNT_EXT_LIBS=lrun50.dll
WIN95_EXT_LIBS=lrun50.dll
LINUX_EXT_LIBS=libLrun50.so
SOLARIS_EXT_LIBS=libLrun50.so
HPUX_EXT_LIBS=libLrun50.sl
AIX_EXT_LIBS=libLrun50.so
LibCfgFunc=lr_configure
ExtMessageQueue=0
WINNT_DLLS=dll_test.dll
5.3, 写个简单的脚本,调用刚才写的 fnlr_dll_test
6.注意点:
6.1 DLL导出函数,需返回整形,如需返回char*型,
LR调研时需加上强制转换,同理,返回结构指针也需强制转换
p = (char*)fnlr_dll_test2(buff, 2); 不然会出错
“have illegal types `pointer to char' and `int'"
6.2 DLL导出函数,动态申请的内存,无法在LR脚本中释放free,
需另写一个free的导出函数。
出错信息: memory violation : Exception ACCESS_VIOLATION received
6.3 LR不支持C++,当然无法导出类,引用调用等c++才有的特征
-
Loadrunner 扩展 --VC2008
2010-10-29 15:43:57
Loadrunner 扩展 包含部分:
扩展介绍---怎么对loadrunner扩展
1. 扩展一: 正则表达式支持
2. 扩展二: MD5加密
3. 扩展三: iconv转码
4. 扩展四: hash支持
5. 扩展五: URL编码
6. 扩展六: 调用LR函数,完善select取值,eval_string内存泄露问题
7. 扩展七: memcache验证码
1. 扩展一: 正则表达式支持
待选方案是boost::regex 或者微软的greta
2. 扩展二: MD5加密
选用网上的C语言实现MD5算法 就成,测试了几个,没问题
3. 扩展三: iconv转码
就用iconv静态库封装了
4. 扩展四: hash支持
boost, stl 等,自己手痒,看到暴雪的hash,简单实现了一下
5. 扩展五: URL编解码
UTF8的URL编码,16进制前加个%, 很简单的一种编解码
6. 扩展六: 调用LR函数
关键是项目要包含LR的头文件和库,然后就可以顺心所欲包装LR常用函数和过程
7. 扩展七: memcache验证码
这个还没实现
未完,请关注后续一一实现细节
-
Testlink1.7.4 升级FCKeditor2.0到2.6
2008-11-03 12:14:29
Testlink1.7.4 自带的FCKeditor版本为2.0,升级到最新的2.6.3
2.6.3更新内容见:http://www.fckeditor.net/whatsnew/all
1. 下载最新版FCKeditor 2.6.3
1.1进入testlink目录:
cd testlink/third_party/
1.2下载文件:
wget http://nchc.dl.sourceforge.net/sourceforge/fckeditor/FCKeditor_2.6.3.tar.gz2. 解压文件
2.1备份fckeditor:
mv fckeditor fckeditor_bak
2.2解压文件:
tar zxvf FCKeditor_2.6.3.tar.gz
3. 修改参数
-----------------------------------------------------------------------------------------------------
修改文件:testlink/third_party/fckeditor/fckconfig.js
------------------------------------------------------------------------------------------------------
修改前:
// FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ; // PHP style server side code
修改后:(去掉注释)
FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ; // PHP style server side code
修改前:
var _FileBrowserLanguage = 'asp' ; // asp | aspx | cfm | lasso | perl | php | py
var _QuickUploadLanguage = 'asp' ; // asp | aspx | cfm | lasso | perl | php | py
修改后:(设置成php)
var _FileBrowserLanguage = 'php' ; // asp | aspx | cfm | lasso | perl | php | py
var _QuickUploadLanguage = 'php' ; // asp | aspx | cfm | lasso | perl | php | py
-----------------------------------------------------------------------------------------------------
修改文件:testlink/third_party/fckeditor/editor/filemanager/connectors/php/config.php
-----------------------------------------------------------------------------------------------------
注意大小写修改前:
$Config['UserFilesPath'] = '/userfiles/' ;
修改后:
$Config['UserFilesPath'] = '/testlink/userfiles/' ;
修改前:
$Config['QuickUploadPath']['File'] = $Config['FileTypesPath']['File'] ;
修改后:
$Config['QuickUploadPath']['File'] = $Config['FileTypesPath']['File'] ;
$Config['QuickUploadPath']['Image'] = $Config['FileTypesPath']['Image'] ;
$Config['QuickUploadPath']['Flash'] = $Config['FileTypesPath']['Flash'] ;
$Config['QuickUploadPath']['Media'] = $Config['FileTypesPath']['Media'] ;
4. 确认创建上传目录
在testlink的下传教userfiles目录
mkdir userfiles
在userfiles目录下创建4个目录
cd userfiles
mkdir file
mkdir flash
mkdir image
mkdir media注: 关于TestLink1.7.4 自带FCKeditor上传图片的问题的解决方法:
见:http://www.51testing.com/?66291/action_viewspace_itemid_96482.html
-
Testlink1.7.4 上传图片问题(linux, php)
2008-11-03 11:30:51
-----------------------------------------------------------------------------------------------------
修改文件:testlink/third_party/fckeditor/fckconfig.js
------------------------------------------------------------------------------------------------------
修改前:
// FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ; // PHP style server side code
修改后:(去掉注释)
FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ; // PHP style server side code
修改前:
var _FileBrowserLanguage = 'asp' ; // asp | aspx | cfm | lasso | perl | php | py
var _QuickUploadLanguage = 'asp' ; // asp | aspx | cfm | lasso | php
修改后:(设置成php)
var _FileBrowserLanguage = 'php' ; // asp | aspx | cfm | lasso | perl | php | py
var _QuickUploadLanguage = 'php' ; // asp | aspx | cfm | lasso | php
------------------------------------------------------------------------------------------------------
修改文件:testlink/third_party/fckeditor_bak/editor/filemanager/browser/default/connectors/php/config.php
------------------------------------------------------------------------------------------------------
修改前:
$Config['Enabled'] = false ;
修改后:
$Config['Enabled'] = true ;
修改前:
$Config['UserFilesPath'] = '/userfiles/' ;
修改后:
$Config['UserFilesPath'] = '/testlink/userfiles' ;
------------------------------------------------------------------------------------------------------
修改文件:testlink/third_party/fckeditor_bak/editor/filemanager/upload/php/config.php
------------------------------------------------------------------------------------------------------
修改前:
$Config['Enabled'] = false ;
修改后:
$Config['Enabled'] = true ;
修改前:
$Config['UserFilesPath'] = '/userfiles/' ;
修改后:
$Config['UserFilesPath'] = '/testlink/userfiles/image/' ;
------------------------------------------------------------------------------------------------------
修改文件:testlink/third_party/fckeditor_bak/editor/filemanager/upload/php/upload.php
------------------------------------------------------------------------------------------------------
修改前:
$sServerDir .= $sType . '/' ;
修改后:
$sServerDir .= strtolower($sType) . '/' ;
修改前:
$sFileUrl = $Config["UserFilesPath"] . $sType . '/' . $sFileName ;
修改后:
$sFileUrl = $Config["UserFilesPath"] . strtolower($sType) . '/' . $sFileName ;
------------------------------------------------------------------------------------------------------
修改文件:创建上传目录
------------------------------------------------------------------------------------------------------
在testlink的下传教userfiles目录
mkdir userfiles
在userfiles目录下创建4个目录
cd userfiles
mkdir file
mkdir flash
mkdir image
mkdir media修改文件比较多,有点复杂,请把fckeditor升级到2.6,修改比较简单
详见:http://www.51testing.com/?66291/action_viewspace_itemid_96484.html
标题搜索
我的存档
数据统计
- 访问量: 14546
- 日志数: 8
- 建立时间: 2008-11-03
- 更新时间: 2013-12-16