开发附带NPAPI插件的Chrome扩展.docx

上传人:b****4 文档编号:3759180 上传时间:2022-11-25 格式:DOCX 页数:12 大小:20.79KB
下载 相关 举报
开发附带NPAPI插件的Chrome扩展.docx_第1页
第1页 / 共12页
开发附带NPAPI插件的Chrome扩展.docx_第2页
第2页 / 共12页
开发附带NPAPI插件的Chrome扩展.docx_第3页
第3页 / 共12页
开发附带NPAPI插件的Chrome扩展.docx_第4页
第4页 / 共12页
开发附带NPAPI插件的Chrome扩展.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

开发附带NPAPI插件的Chrome扩展.docx

《开发附带NPAPI插件的Chrome扩展.docx》由会员分享,可在线阅读,更多相关《开发附带NPAPI插件的Chrome扩展.docx(12页珍藏版)》请在冰豆网上搜索。

开发附带NPAPI插件的Chrome扩展.docx

开发附带NPAPI插件的Chrome扩展

开发附带NPAPI插件的Chrome扩展

1NPAPI插件2

1.1NPAPI简介2

1.2准备工作2

1.3创建插件2

1.3.1创建Win32DLL工程2

1.3.2引入NPAPI库2

1.3.3添加宏定义_X86_2

1.3.4添加模块定义文件(.def文件)2

1.3.5编辑stdafx.h文件3

1.3.6添加基础框架文件3

1.3.7编辑sample.cpp文件3

1.3.8编辑sample.h文件4

1.3.9添加Version资源8

1.3.10编译输出8

1.4需要注意的问题8

1.4.1库文件的捆绑8

1.4.2谨记MIMEType8

1.4.3无效的NPN_CreateObject?

8

2Chrome扩展9

2.1简介9

2.2开始编写9

2.2.1准备一个图标文件(.png)9

2.2.2准备NPAPI插件(.dll)9

2.2.3编写manifest.json9

2.2.4编写background.html10

2.2.5编写background.js10

2.3安装与测试10

2.4发布10

3参考资料11

1NPAPI插件

1.1NPAPI简介

NPAPI(NetscapePluginApplicationProgrammingInterface,网景插件应用程序接口)是网景公司当年制定的开发基于网景浏览器,用于在浏览器中执行外部应用程序的通用接口。

该接口基于插件机制,制定了一系列的标准和API,因此也有NPAPI插件一说。

同期的微软,也在IE中支持ActiveX为浏览器插件,不得不承认微软在这一点上,把浏览器和OS结合的更为紧密,这也可能是当年微软能够击溃网景的原因之一。

但网景的影响深远,除了微软特立独行之外,其他浏览器开发厂商奇迹般的都一致采用了NPAPI来对浏览器进行扩展(这包括后来从灰烬中重生的FireFox及新生的Chrome;当然,Chrome在不久前时间已经在尝试抛弃NPAPI了)。

因此,在目前来看NPAPI几乎是IE之外的浏览器插件开发的统一标准。

1.2准备工作

根据参考资料,从ftp:

//ftp.mozilla.org/pub/mozilla.org/firefox/releases/4.0.1/source/中下载了firefox早期的源代码,并从中抠出了NPAPI相关的部分(恩,资料上说的不够详细)。

解压源代码,把modules\plugin\base\public和modules\plugin\sdk\samples\include两个目录中的文件复制出来放在一起(我创建了D:

\npapi,把文件都放这了)。

另外,资料里提到的三个文件在modules\plugin\sdk\samples\common下(记住位置,待会会用到)。

1.3创建插件

顺便提一下,本文以VS2003为范例。

插件实现的功能:

对浏览器(贴切点说是对javascript引擎)暴露对象Sample,而Sample又提供了一个sayHello的方法。

这样一来,我们可以在浏览器中,使用javascript通过Sample.sayHello();来调用插件所提供的功能。

1.3.1创建Win32DLL工程

1.3.2引入NPAPI库

在工程属性中,添加“附加包含目录”:

D:

\npapi(之前抠出来的部分)。

1.3.3添加宏定义_X86_

1.3.4添加模块定义文件(.def文件)

创建sample.def文件,内容为:

LIBRARY"sample"

EXPORTS

NP_GetEntryPoints@1

NP_Initialize@2

NP_Shutdown@3

1.3.5编辑stdafx.h文件

增加tchar头文件的引入:

#include

增加NPAPI头文件的引入:

//Mozilla-API

#include

#include

#include"npruntime.h"

1.3.6添加基础框架文件

找到np_entry.cpp、npn_gate.cpp和npp_gate.cpp,复制到工程目录下,并添加到工程(恩恩,位置在modules\plugin\sdk\samples\common)。

在编辑器里分别打开着三个文件,并在文件头部加入:

#include"stdafx.h"

1.3.7编辑sample.cpp文件

将文件代码修改为:

#include"stdafx.h"

#include"sample.h"

NPErrorNS_PluginInitialize()

{

returnNPERR_NO_ERROR;

}

voidNS_PluginShutdown()

{

}

nsPluginInstanceBase*NS_NewPluginInstance(nsPluginCreateData*aCreateDataStruct)

{

if(!

aCreateDataStruct)

returnNULL;

CPlugin*plugin=newCPlugin(aCreateDataStruct->instance);

returnplugin;

}

voidNS_DestroyPluginInstance(nsPluginInstanceBase*aPlugin)

{

if(aPlugin)

delete(CPlugin*)aPlugin;

}

1.3.8编辑sample.h文件

如果文件不存在,创建一个,并添加到工程。

将文件内容修改为:

#include"stdafx.h"

#include"npruntime.h"

#include"pluginbase.h"

boolIsStringNPIdentifier(NPIdentifiername)

{

return*(char**)name==(char*)name+8;

}

char*CopyNPString(NPStringstr)

{

char*r=newchar[str.UTF8Length+1];

strncpy(r,str.UTF8Characters,str.UTF8Length);

r[str.UTF8Length]=0;

returnr;

}

classCSample:

publicNPObject

{

public:

CSample(NPPnpp):

mNpp(npp){}

~CSample(){}

staticNPObject*_Creator(NPPnpp,NPClass*aClass){returnnewCSample(npp);}

staticvoid_Deallocate(NPObject*npobj){delete(CSample*)npobj;}

staticvoid_Invalidate(NPObject*npobj){((CSample*)npobj)->Invalidate();}

staticbool_HasMethod(NPObject*npobj,NPIdentifiername){return((CSample*)npobj)->HasMethod(name);}

staticbool_Invoke(NPObject*npobj,NPIdentifiername,constNPVariant*args,uint32_targCount,NPVariant*result){return((CSample*)npobj)->Invoke(name,args,argCount,result);}

staticbool_InvokeDefault(NPObject*npobj,constNPVariant*args,uint32_targCount,NPVariant*result){return((CSample*)npobj)->InvokeDefault(args,argCount,result);}

staticbool_HasProperty(NPObject*npobj,NPIdentifiername){return((CSample*)npobj)->HasProperty(name);}

staticbool_GetProperty(NPObject*npobj,NPIdentifiername,NPVariant*result){return((CSample*)npobj)->GetProperty(name,result);}

staticbool_SetProperty(NPObject*npobj,NPIdentifiername,constNPVariant*value){return((CSample*)npobj)->SetProperty(name,value);}

staticbool_RemoveProperty(NPObject*npobj,NPIdentifiername){return((CSample*)npobj)->RemoveProperty(name);}

staticbool_Enumerate(NPObject*npobj,NPIdentifier**identifier,uint32_t*count){return((CSample*)npobj)->Enumerate(identifier,count);}

staticbool_Construct(NPObject*npobj,constNPVariant*args,uint32_targCount,NPVariant*result){return((CSample*)npobj)->Construct(args,argCount,result);}

virtualvoidInvalidate(){}

virtualboolHasMethod(NPIdentifiername)

{

if(IsStringNPIdentifier(name))

{

char*methodName=*(char**)name;

if(_tcscmp(methodName,TEXT("sayHello"))==0)

returntrue;

}

returnfalse;

}

virtualboolInvoke(NPIdentifiername,constNPVariant*args,uint32_targCount,NPVariant*result)

{

if(IsStringNPIdentifier(name))

{

char*methodName=*(char**)name;

if(_tcscmp(methodName,TEXT("sayHello"))==0)

{

MessageBox(NULL,TEXT("hello,npapi."),TEXT("plugin-sample"),MB_OK|MB_ICONINFORMATION);

returntrue;

}

}

returnfalse;

}

virtualboolInvokeDefault(constNPVariant*args,uint32_targCount,NPVariant*result){returntrue;}

virtualboolHasProperty(NPIdentifiername){returnfalse;}

virtualboolGetProperty(NPIdentifiername,NPVariant*result){returnfalse;}

virtualboolSetProperty(NPIdentifiername,constNPVariant*value){returnfalse;}

virtualboolRemoveProperty(NPIdentifiername){returnfalse;}

virtualboolEnumerate(NPIdentifier**identifier,uint32_t*count){returnfalse;}

virtualboolConstruct(constNPVariant*args,uint32_targCount,NPVariant*result){returnfalse;}

private:

NPPmNpp;

};

staticNPClassSample={

NP_CLASS_STRUCT_VERSION_CTOR,

CSample:

:

_Creator,

CSample:

:

_Deallocate,

CSample:

:

_Invalidate,

CSample:

:

_HasMethod,

CSample:

:

_Invoke,

CSample:

:

_InvokeDefault,

CSample:

:

_HasProperty,

CSample:

:

_GetProperty,

CSample:

:

_SetProperty,

CSample:

:

_RemoveProperty,

CSample:

:

_Enumerate,

CSample:

:

_Construct

};

 

classCPlugin:

publicnsPluginInstanceBase

{

public:

CPlugin(NPPpNPInstance):

nsPluginInstanceBase(),m_pNPInstance(pNPInstance),m_bInitialized(FALSE),m_sample(NULL){}

~CPlugin(){}

NPBoolinit(NPWindow*pNPWindow)

{

m_bInitialized=TRUE;

returnTRUE;

}

voidshut()

{

if(m_sample)

{

//NPN_ReleaseObject(m_sample);

deletem_sample;

m_sample=NULL;

}

m_bInitialized=FALSE;

}

NPBoolisInitialized()

{

returnm_bInitialized;

}

NPErrorGetValue(NPPVariablevariable,void*value)

{

switch(variable)

{

caseNPPVpluginNameString:

*((char**)value)="plugin-sample";

break;

caseNPPVpluginDescriptionString:

*((char**)value)="plugin-sampleforChrome";

break;

caseNPPVpluginScriptableNPObject:

//if(m_sample==NULL)

//m_sample=(CSample*)NPN_CreateObject(m_pNPInstance,&Sample);

//

//if(m_sample!

=NULL)

//NPN_RetainObject(m_sample);

if(m_sample==NULL)

{

m_sample=newCSample(m_pNPInstance);

m_sample->_class=&Sample;

}

*((NPObject**)value)=m_sample;

break;

}

returnnsPluginInstanceBase:

:

GetValue(variable,value);

}

private:

NPPm_pNPInstance;

NPBoolm_bInitialized;

CSample*m_sample;

};

1.3.9添加Version资源

以文本编辑器方式打开资源文件,在版本信息BLOCK中添加:

VALUE"MIMEType","application/plugin-sample"

1.3.10编译输出

自此,sample.dll已经躺在Debug目录下了。

1.4需要注意的问题

1.4.1库文件的捆绑

考虑到工程的独立性,我们可以把库文件与工程捆绑在一起,我的做法是在工程内创建一个inc目录,把之前提到的D:

\npapi下所有文件复制过来,并把“附加包含目录”改为:

inc。

1.4.2谨记MIMEType

一定要记得添加Version资源,并添加MIMEType项。

1.4.3无效的NPN_CreateObject?

在后续的测试过程中,NPN_CreateObject总是无法有效的创建对象。

因此,在sample.h中,我们采用了直接newCSample();的方式(具体原因有待研究)。

2Chrome扩展

2.1简介

不愧是Google出品,Chrome从一推出就受到了业界大量的关注和用户的青睐,几年下来,市场份额一直在膨胀。

其中原因不仅是小巧轻量和启动快速,也有其快速支持最新Web标准等多方面的缘故。

对于第三方开发商,Google也提供了Chrome扩展编程接口,用来提升浏览器本身的个性化定制。

Chrome扩展基于HTML5构建,面向javascript引擎暴露浏览器内部对象,使用javascript即可直接操作浏览器对象,从而实现功能扩展。

当然,如果我们希望实现的功能超出了Chrome本身提供的内置对象所涵盖的范围,则需要之前提到的NPAPI插件的支持了(这就类似IE浏览器中通过newActiveXObject创建COM对象来增强浏览器功能一样)。

2.2开始编写

哦哦,提醒一下,下面提到的所有文件,务必放到同一个目录中。

扩展实现的功能:

在每个页面(空白处)的右键菜单中,添加“sayHello”菜单项,用户点击这个菜单项时,扩展程序通过调用NPAPI插件的sayHello方法,实现弹出“hello,npapi.”对话框的功能。

2.2.1准备一个图标文件(.png)

去网上下载一个png文件吧,32x32、48x48、64x64、128x128等尺寸的都可以。

总之,这是一件彰显个性的事情。

2.2.2准备NPAPI插件(.dll)

恩,之前编译好,已经在Debug目录躺的妥妥的sample.dll,把他复制过来吧。

2.2.3编写manifest.json

内容如下:

{

"manifest_version":

2,

"minimum_chrome_version":

"6.0.0.0",

"name":

"我的扩展",

"description":

"我的扩展",

"version":

"1.0.0",

"permissions":

[

"contextMenus",

"tabs",

"http:

//*/*",

"https:

//*/*"

],

"icons":

{

"128":

"sayHello.png"

},

"background":

{

"page":

"background.html"

},

"plugins":

[

{"path":

"sample.dll","public":

true}

]

}

2.2.4编写background.html

内容如下:

2.2.5编写background.js

内容如下:

varbkgnd=chrome.extension.getBackgroundPage();

varsample=bkgnd.document.getElementById("Sample");

functiongetClickHandler(type){

returnfunction(info,tab){

varurl=info.pageUrl;

vartitle=tab.title;

if(type=="page"){

sample.sayHello();

}

}

}

chrome.contextMenus.create({"title":

"sayHello","type":

"normal","contexts":

["page"],"onclick":

getClickHandler("page")});

2.3安装与测试

打开Chrome设置的“扩展程序”页面,勾选“开发者模式”,点击“加载正在开发的扩展程序”,在弹出的对话框中,选择Chrome扩展所在的目录,然后再确认“添加”即可。

2.4发布

同上,在开发者模式下,选择“打包扩展程序”,在弹出的对话框中,选择Chrome扩展所在的目录,然后再次点击“打包扩展程序”即可(第一次打包时,Chrome会自动生成一个密钥文件;以后每次打包,都需要选择这个密钥文件)。

打包之后的Chrome扩展,是一个.crx的zip压缩文件,可以直接拖拽到Chrome的扩展程序页面,实现安装。

3参考资料

Mozilla官方文档(英文):

https:

//developer.mozilla.org/en-US/docs/Plugins

https:

//developer.mozilla.org/en-US/docs/Gecko_Plugin_API_Reference/Plug-in_Basics

NPAPI开发详解(中文):

http:

//

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1