我有一个 html 页面,它打开一个新窗口并加载一个基本的 NPAPI 编写的插件,我打开一个 Wide Save 对话框,然后使用 java 脚本函数调用 NPN_GetURL 来关闭窗口。每次 Firefox 崩溃并且 Chrome 都会显示插件崩溃。我不确定问题是 HTML 和 JS 还是插件的问题。在谷歌搜索其他类似问题时,我没有找到很多东西。下面是我加载插件的页面,插件调用了 javascript 函数“removePlugin”。至于firefox在3.6中没有问题只有在版本4中
----开始
<html>
<script language="javascript">
function removePlugin()
{
var plgn = document.getElementById("myplugin1");
document.getElementById("div1").removeChild(plgn);
setTimeout('doClose()', 2000);
}
function doClose()
{
window.close();
}
</script>
<body >
<div id="div1">
<embed type="application/x-My-Plugin" id="myplugin1"></embed>
</div>
</body>
</html>
----结束
----插件代码开始
#include "npapi.h"
//Prottype
LRESULT CALLBACK PluginWindowProc (HWND,UINT,WPARAM,LPARAM);
//Define
#define MY_MESSAGE WM_USER + 1000
//Global
const char* gInstanceLookupString = "instance";
WNDPROC fDefaultWindowProc;
//Function: NPP_SetWindow
NPError NPP_SetWindow(NPP instance,
NPWindow *window)
{
fDefaultWindowProc = (WNDPROC)SetWindowLongPtr((HWND)window->window,
GWL_WNDPROC,
(LONG)PluginWindowProc);
SetProp(window->window,
gInstanceLookupString,
(HANDLE)instance);
SendMessage(window->window,
MY_MESSAGE,
0,
0);
return NPERR_NO_ERROR;
}
//PluginWindowProc
LRESULT CALLBACK PluginWindowProc(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
OPENFILENAMEW ofn; //Fix.3a
WCHAR szFile[512]; //File name that appears in the Save Dialog box //Fix.3a
NPP instance;
switch(Msg)
{
case MY_MESSAGE:
instance = (NPP)GetProp(hWnd,
gInstanceLookupString);
//SAVE----------------------------------------
memset(&ofn,
0x00,
sizeof(OPENFILENAMEW));
memset(szFile,
0x00,
sizeof(szFile));
_snwprintf_s(szFile,
_countof(szFile),
_countof(szFile),
L"Test.Txt");
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFile = szFile;
ofn.nMaxFile = _countof(szFile);
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
GetSaveFileNameW(&ofn);
//CLOSE---------------------------------------
NPN_GetURL(instance,
"javascript:removePlugin(0);",
"_self");
//--------------------------------------------
break;
default:
CallWindowProc(fDefaultWindowProc,
hWnd,
Msg,
wParam,
lParam);
break;
}
return 0;
}
//Function: NPP_Destroy
NPError NPP_Destroy(NPP instance,NPSavedData **save){return NPERR_NO_ERROR;}
//Function: NPP_DestroyStream
NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason){return NPERR_NO_ERROR;}
//Function: NPP_HandleEvent
int16 NPP_HandleEvent(NPP instance,void* event){return 0;}
//Function: NPP_Initialize
NPError NPP_Initialize(void){return NPERR_NO_ERROR;}
//Function: NPP_New
NPError NPP_New(NPMIMEType pluginType,NPP instance, uint16 mode, int16 argc,char* argn[], char * argv[],NPSavedData* saved){return (NPERR_NO_ERROR);}
//Function: NPP_NewStream
NPError NPP_NewStream(NPP instance,NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype){ return NPERR_NO_ERROR;}
//Function: NPP_Print
void NPP_Print(NPP instance, NPPrint *printInfo){}
//Function: NPP_Shutdown
void NPP_Shutdown(void){}
//Function: NPP_StreamAsFile
void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname){}
//Function: NPP_URLNotify
void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData){}
//Function: NPP_Write
int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer) {return 0;}
//Function: NPP_WriteReady
int32 NPP_WriteReady(NPP instance, NPStream *stream){return 0;}
----插件代码结束
最佳答案
确实很难确定到底发生了什么,但我可以告诉您,您所采取的方法还有其他几个问题。首先也是最重要的是,您绝对不能阻塞主浏览器线程,这就是当您在主浏览器中打开对话框时发生的情况。现在,我意识到,当您的对话框打开时,您可能会没事(有些人甚至可能误以为其他人会没事)对话框锁定(不,不仅仅是阻止输入,而是实际上锁定)浏览器,但是在当前所有浏览器在进程外运行插件并且在对话框打开时不会完全锁定的情况下,浏览器至少会询问用户是否想要杀死插件,如果不是像 Safari 5.1 那样直接杀死你的插件。
如果您要使用对话框,您真正需要做的是启动另一个线程并对其进行对话框调用,然后在完成后回调到浏览器(在主线程上!使用 NPN_PluginThreadAsyncCall) .
至于崩溃日志,从它的说法来看,您以某种方式破坏了浏览器对插件的句柄,因为当它尝试在您的插件上调用 SetWindow 时,它会崩溃。您可能需要考虑在 NPAPI 上放弃这个准系统尝试并使用类似 FireBreath 的东西。 ,其中棘手的 NPAPI 位已经为您解决了。
关于javascript - NPAPI 插件,从网页中删除Child 会导致 Firefox4 和 Chrome 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6331924/