I have NPAPI plugin for Mac Safari/fire Fox browser.The plugins has several method and I can call it from java script.I wanted to know whether I can close or unload the plugin through implementing method inside it.I need this function to unload the plugin from browser/memory.
Short answer: No.
Longer answer: not really. What you can do is remove the object tag from the DOM, which will cause that instance to be unloaded. It makes no guarantees that the browser will unload the module, but it does at least get the instance out of your way.
Most people who want to do that are trying to find a way to update the plugin without closing the browser; you can do this, but you need to install the new plugin with a different filename than the old plugin. I'm talking about the filename of the .plugin/ bundle, not the binary inside it.
If you have a plugin in ~/Internet Plugins/MyPlugin-1.0.0.0 and you delete that and put a new plugin in ~/Internet Plugins/MyPlugin-1.0.0.1 and then in javascript you call navigator.plugins.refresh(false); the browser will find the new plugin and when you instantiate it it'll give you the new version. The bundle has to be named differently, though; that's the key.
Related
I have successfully compiled and created npapi dll in MS based on mozilla npruntime project. Reference from: https://developer.mozilla.org/en-US/docs/Compiling_The_npruntime_Sample_Plugin_in_Visual_Studio.
Starting mozilla and open about:plugins shows the plugin. But when I open "test.html" the plugin does'nt come up.
I have tested the dll by making a separate test app, where i can access the entry point functions through
NP_INIT l_pInit= (NP_INIT)GetProcAddress(hModule, "NP_Initialize");
and i am able to step into my plugin dll function.
But with mozilla it doesn't work. Please suggest.
You can debug directly the mozilla process. Just attach to the process. However, modern browsers uses separate process for loading the third party plugins, so you will have to attach to that process. Than you can set breakpoints to loading routine (NP_GetEntryPoints, NP_Initialize) and see what is happening in there.
Also, if you have trouble with attaching to the process, you can simply show debug dialogs from your code and narrow the problem area.
UPDATE 1:
It seems like the browser does nto know that it should use the plugin. Did you specify the MIME type of hwat your plugin is for? If so, run the following script in an HTML page:
<embed type="application/x-my-extension" id="pluginId">
<script>
var plugin = document.getElementById("pluginId");
var result = plugin.myPluginMethod(); // call a method in your plugin
console.log("my plugin returned: " + result);
</script>
x-my-extensionreplace with your extension which you used in NP_GetMimeDescription. You shoudl check in about:plugins if the browser registered your plugin correctly for correct MIME type.
Sounds like there is most likely something wrong in your plugin initialization; you might try using FireBreath to create a npapi plugin, as it will be a lot less work and work on IE as well. If you don't like that idea, you could look at other npapi plugins (including FireBreath) to make sure you're doing things correctly. Add logging (of whichever type you like) to the main entrypoints and see which point it fails at.
Another trick is to go to about:config and find the plugins ipc settings and disable them; then you can attach to the main firefox process and it should hit your breakpoints if they are being called.
See the FireBreath Debugging Plugins page for other ideas.
Thanks guyz. Finally i am able to load and access the functionality of my plugin in the browser. Following are the findings:-
1. Even though my plugin's MIME type in resource file was 'application/mozilla-npruntime-scriptable-plugin'. But i need to access it from javascript embed element through 'application/x-npruntime-scriptable-plugin'. After this step the debugger started breaking on my plugin's break points.
2. The check of size of NPPluginFuncs and NPNetscapeFuncs was failing, may be because of different version of NPAPI implemented in my firefox.
At the end i got startup and thank you all for your support.
I'm developing a plugin using FireBreath on Windows (for now) that among other things is displaying a webcam feed using OpenGL. I'm using a windowed plugin and I'm drawing from a separate thread. The code can be viewed here:
Header file
https://github.com/EvilTengil/kinect-at-home-plugin/blob/0007beecf136ff2e5e1aa50be94d4906447a8f43/Win/KinectAtHomeWin.h
Source file
https://github.com/EvilTengil/kinect-at-home-plugin/blob/0007beecf136ff2e5e1aa50be94d4906447a8f43/Win/KinectAtHomeWin.cpp
(Ignore the strange code in onWindowResized, it's just some testing that remained in the commit.)
The problem is that as soon as the browser window is re-sized so that the visible region of the plugin is changed or the the extension is somehow scrolled outside the visible area of the scroll box, the plugin crashes in Chrome. I haven't got Firefox installed but I'm guessing it's a NpApi thing, since it's working in Internet Explorer.
I believe what is happening is that Chrome releases and creates a new HDC whenever the visible dimensions of the plugin is changed. This probably results in that the Rendering Context is invalid, but it is still being used in the plugin and that causes the crash.
I've noticed NPP_SetWindow get's called when this happens, but those calls are ignored in NpapiPluginModule_NPP.cpp, so my there is no way of hooking in to this event.
I've Google for several hours now but without finding any help. Does anyone have any experience of this?
I have an idea that it could work if I created my own child window to the plugin window where I could handle my own DC. I did some quick testing that failed, which is probably because of my lame Win32 skills. But could this work with some more work? Another idea I have is to track the visible region somehow, but I haven't looked in to this yet.
Windows handles getting invalid should not cause a program to crash per so. But OpenGL, namely its extensions require some special precautions, especially if the host program makes use of OpenGL as well.
Any kind of plugin or DLL that makes use of OpenGL must take care, that is puts its required resources into a sane state before using them, and put them back once done. For OpenGL this means, everytime before you start using it you should rebind your context:
HDC hOldDC = wglGetCurrentDC();
HRC hOldContext = wglGetCurrentContext();
// first unbind old context/DC from current thread
wglMakeCurrent(NULL, NULL);
// then bind our context
wglMakeCurrent(hMyDC, hMyContext);
// this is essential, as in Windows the addresses of extensions
// may depend on the active context, so you must reinitialise
// extension function pointers!
reinitialize_extensions();
/* NOW USE OPENGL FUNCTION
// cleaning up once we're done:
wglMakeCurrent(NULL, NULL);
wglMakeCurrent(hOldDC, hOldRC);
// remember that we also need to reset extension
// function pointers to the other context
reinitialize_extensions();
Since in Window extension functions pointers depend on the context it makes sense to put them into a structure and call them through that one. This saves the whole extension reinitialisation thing. In C++ you could wrap the whole OpenGL context in a class for this.
Remember that you need to go through this setup/teardown everytime your plugin gets called through NP-API.
I have a NPAPI plugin developed for Chrome. It works ok. But now I need to call NPN_GetValue from the plugin. The question is, how can I link (either statically, or dynamically) my code and what library/binary should be used for imports? I searched through all Chrome binaries and I did not find a single one, which contains NPN_ exports. Surely NPN_ methods must be provided by hosting browser.
Thanks in advance.
The function pointers are provided to you as an argument to NP_Initialize; it's your job to keep them around so that you can call them later. The functions aren't exported for you to link to.
I have a NPAPI plugin, incorporated into Chrome extension, and defined in manifest file as public. When an object tag with the plugin's mime type is inserted into background page of the extension, the plugin loads ok. When the same object tag is inserted into an arbitrary webpage using chrome.tabs.executeScript, it fails to load. If the plugin itself is placed into Plugins folder (and loaded into the browser), then the objects with the appropriate mime type are inserted into arbitrary web-pages successfully.
The question is why the plugin does not load properly into arbitrary web-page, when it is deployed within the extension and marked as public (so it is supposed to be available for any page, as far as I know).
You should use mark the plugin with "public": true in your extensions’s manifest. The plugin should show up in about:plugins.
If the plugin shows up, confirm that the MIME type and file extensions in about:plugins matches the type of the embed element being injected into the page. Also check to see if other plugins have the same MIME type. If a plugin that is listed earlier has the same MIME type, that plugin will be loaded.
If your plugin doesn’t show up, or it shows up but does not work, you’ve got more detective work to do:
You can start Chrome with the --debug-plugin-loading flag to get extra logging from the plugin infrastructure. Some of these messages look like this:
[24634:-1392008512:1466799063452984:ERROR:plugin_list.cc(358)] Loading plugin /Library/Internet Plug-Ins/Flash Player.plugin
Despite containing the word ERROR, these messages are not errors. ERROR is just the log level. Use Chromium Code Search and the files mentioned in the log (for example plugin_list.cc) to read the log messages in context. Chrome uses a multi-process architecture. So remember that the output might intersperse log messages from different processes.
If you have the source of your plugin, you put logging statements in your plugin code. For example, on OS X you could write:
NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) {
NSLog(#"FOO NP_GetEntryPoints");
…
and then
2012-08-20 11:22:56.799 Google Chrome Helper EH[23544:b03] FOO NP_GetEntryPoints
will show up in the log. These log statements can give you further clues about how far plugin loading is getting before it fails.
It will take some effort, but you could build Chromium from scratch and use the --plugin-launcher command line option to get source-level debugging of the plugin loader.
Posting an answer with my comment(s) as requested =]
If you install an extension with a public plugin (and everything is installed correctly) then it will show up in about:plugins. Therefore, there is something wrong with your extension/plugin installation. unfortunately, that's all I know.
about:plugins as noted in the comments will display all plugins that are public whether installed as public plugins in an extension or just installed as NPAPI plugins.
Hey I got a quick question:
I have got a chrome extension that adds a popup page to the toolbar. It accepts input from the user then calls a NPAPI dll which generates an XML file. I would like to be able to, after the NPAPI dll finishes its work, create a new tab which would open to the newly generated XML page.
Can anyone help me out with this?
Thanks.
You can let your NPAPI communicate to JavaScript via NPN_Invoke. NPN_Invoke will allow you to invoke a method on a given NPObject.
For example, you can construct your method NPN_GetStringIdentifier, and use that to execute a method in your popup.
You can refer to this article, on how to communicate back to JavaScript from NPAPI plugin. The example shown there is a simple console.debug("Hello from C++")
Update
I noticed you want to open the xml file right after. Did you save the XML file in the location of the extension folder?
C:\Users\[user]\AppData\Local\Google\Chrome\User Data\Default\Extensions\[extension_id]\[extension_version]
Then you can open it with chrome.extension.getURL([file]);
But, it would be great if you return the XML file and open it within the extension itself.
Ideally you don't put the logic for UI behavior into the plugin, but in the extension. The plugin should tell the extension where the XML file is located and the extension should handle the rest.
This could be done two ways:
Synchronously returning the location is easy: You do the work directly from the Invoke() implementation of your plugin and return a string containing the location of the file to the script.
This of course has the downside of blocking the main- (and GUI-)thread until processing is done and thus is no option when processing is not done quickly.
Asynchronously returning it is a bit more work: Ideally you allow the extension to specify a callback function that should be invoked when processing is done. This could be achieved by either handling addEventListener() accordingly or by allowing the script to pass a callback as a parameter when it initiates the XML processing. The XML processing function then starts or feeds another thread doing the actual work and returns immediately. When the processing is done you call NPN_InvokeDefault() on the stored function object to call it.
Beware: Calling into JavaScript always has to be done on the main thread.