Dokumentacja wtyczek Gecko:Przegląd tworzenia wtyczek
z Mozilla Developer Center, polskiego centrum programistów Mozilli.
UWAGA: Tłumaczenie tej strony nie zostało zakończone.
Może być ona niekompletna lub wymagać korekty.
Chcesz pomóc? | Dokończ tłumaczenie | Sprawdź ortografię | Więcej takich stron...
[edytuj] Pisanie wtyczek
Kiedy już zdecydujesz sie napisać wtyczkę proces jej tworzenia jest prosty. Poniższe kroki ilustrują tenże proces:
- Zaplanuj wtyczkę: zdecyduj jakie usługi ma ona dostarczać, w jaki sposób współdziałać z przeglądarką oraz jakie media obsługiwać.
- Wybierz typ MIME i rozszerzenie wtyczki (Rejestrowanie wtyczek).
- Ustaw odpowiedni swoje środowisko programistyczne. Możesz używać różnych środowisk, ale upewnij się, że posiadasz odpowiednie pliki ze źródeł Mozilli lub z SDK wtyczki.
- Stwórz projekt wtyczki.
You can either start from one of the samples provided for your operating system in the mozilla source directory, where plug-ins samples are already being built, or you can construct a new plug-in project in your own development environment using SDK-provided files. See the README in the plug-in SDK for more information about using the SDK and using the samples provided there. - Write your plug-in code and implement the appropriate Plug-in API methods for basic plug-in operation. You'll find an overview of the Plug-in API methods in this chapter, as well as separate chapters for all of the major functional areas of the Plug-in API. Also see Making Plug-ins Scriptable for more information about making plug-ins accessible from the browser.
- Build the plug-in for your operating system. See "Building Plug-ins"
- Install the plug-in in the plug-in directory for your operating system. See Installing Plug-ins.
- Test your plug-in and debug as necessary.
- Create an HTML page and embed the plug-in object. For information about the HTML elements to use, see Using HTML to Display Plug-ins. To see your plug-in in action, simply display the HTML page that calls it in the browser.
[edytuj] Rejestrowanie wtyczek
Netscape Gecko identifies a plug-in by the MIME type it supports. When it needs to display data of a particular MIME type, the browser finds and invokes the plug-in object that supports that type. The data can come from either an object element in an HTML file (where the object or embed element either specifies the MIME type directly or references a file of that type), from a separate non-HTML file of that MIME type, or from the server.
The server looks for the MIME type registered by a plug-in, based on the file extension, and starts sending the file to the browser. The browser looks up the media type, and if it finds a plug-in registered to that type, loads the plug-in software.
When it starts up, the browser checks for plug-in modules in the plug-in directory for the platform and registers them. It determines which plug-ins are installed and which types they support through a combination of user preferences that are private to the browser and the contents of the plug-ins directory.
A MIME type is made up of a major type (such as application or image) and a minor type, for example, image/jpeg. If you define a new MIME type for a plug-in, you must register it with IETF (Internet Engineering Task Force). Until your new MIME type is registered, preface its name with "x-", for example, image/x-nwim. For more information about MIME types, see these MIME RFCs:
- RFC-1521: "MIME: Mechanisms for Specifying and Describing the Forms of Internet Message Bodies"
- RFC-1590: "Media Type Registration Procedure."
There are some variations to how plug-ins are handled on different platforms. The following sections describe platform-specific discovery and registration:
[edytuj] MS Windows
On Windows, the plugins directory is located in the same directory as the browser application. Typical installations locate the plugins directory here:
C:\Program Files\Mozilla Firefox\Plugins
You can also find this directory through the Registry. The browser does not search subdirectories. Plug-ins must have a 8.3 filename beginning with NP and ending with .DLL.
The Windows version information for the plug-in DLL determines the MIME types, file extensions, file open template, plug-in name, and description. In the MIME types and file extensions strings, multiple types and extensions are separated by the "|" character, for example:
video/quicktime|audio/aiff|image/jpeg
For the browser to recognize the plug-in, the version stamp of the plug-in DLL must contain the following lines:
- File Extents: for file extensions
- MIME Type: for MIME types
- Language: for language in use
In your development environment, make sure your language is set to "US English" and the character set to "Windows Multilingual." The resource code for this language and character set combination is 040904E4.
[edytuj] Unix
On Unix, plug-ins are found according to the section How Gecko Finds Plug-ins. Note that exported function begin with NP while browser called function in the plugin begin with NPP.
To determine the MIME types and file extensions that the plug-in handles, the browser loads each library and calls into the NP_GetMIMEDescription entry point. This exported C function should return a string containing the type, extension list, and type description separated by semicolons. For example: image/xbm;xbm;X Bitmap. This information will then appear in the JavaScript object navigator.mimetypes array which populates about:plugins.
NPP_GetValue is called after the plugin is initialized to get the scripting interface while NP_GetValue is called during initialization to retreive the plug-in's name and description which will appear in the JavaScript object navigator.plugins array which populates about:plugins.
Caution: Gecko caches the values returned by these functions and will only call it if the plug-ins timestamp has changed. See błąd 125469.
[edytuj] Mac OS X
On Mac OS X, if Gecko finds a NP_GetMIMEDescription entry point, it will use the information returned by this function instead of looking in the resources.
Mac OS X plug-ins are found according to the section How Gecko Finds Plug-ins. Plug-ins are identified by file type NSPL. The MIME types supported by a plug-in are determined by its resources. 'STR#' 128 should contain a list of MIME types and file extensions in alternating strings. For example:
| str 128 | MIME type |
| String 1 | video/quicktime |
| String 2 | mov, moov |
| String 3 | audio/aiff |
| String 4 | aiff |
| String 5 | image/jpeg |
| String 6 | jpg |
Several other optional strings may contain useful information about the plug-in. Plug-ins must support 'STR#' 128 but are not required to support any of these others:
- STR#' 127 can contain a list of MIME type descriptions corresponding to the types in 'STR#' 128 . For example, this description list corresponds to the types in the previous example: String 1: "QuickTime Video", String 4: "AIFF Audio", and String 5: "JPEG Image Format."
- STR#' 126: String 1 can contain a descriptive message about the plug-in. This message, which is in HTML format, is displayed by the browser in its "About Plug-ins" page. String 2 can contain the name of the plug-in, thus allowing the name the user sees to be different from the name of the file on disk.
[edytuj] Rysowanie instancji wtyczki
Before drawing itself on the page, the plug-in must provide information about itself, set the window or other target in which it draws, arrange for redrawing, and handle events.
A windowless plug-in can call the following Netscape methods to draw itself:
- NPN_ForceRedraw: Force a paint message for windowless plug-ins.
- NPN_InvalidateRect: Invalidate an area in a windowless plug-in before repainting or refreshing.
- NPN_InvalidateRegion: Invalidate an area in a windowless plug-in before repainting or refreshing.
The browser calls these Plug-in methods:
- NPP_GetValue: Query the plug-in for information.
- NPP_Print: Request a platform-specific print operation for the instance.
- NPP_SetValue: Set the browser information.
- NPP_SetWindow: Set the window in which a plug-in draws.
- NPP_HandleEvent: Deliver a platform-specific event to the instance.
The plug-in can call these Netscape methods to query and set information:
- NPN_GetValue: Get the browser information.
- NPN_SetValue: Set plug-in the browser information.
For information about these processes, see Drawing and Event Handling
[edytuj] Obsługa pamięci
Programiści wtyczki mogą skorzystać z własności pamięci dostarczonych przez API wtyczki, by alokować i z zwalniać pamięć.
- Użyj metody NPN_MemAlloc do alokacji pamięci z przeglądarki.
- Użyj metody NPN_MemFree do zwolnienia pamięci alokowanej za pomocą NPN_MemAlloc.
- Użyj metody NPN_MemFlush do zwolnienia pamięci (wyłącznie Mac OS) przed wykonywaniem wywołań Mac Toolbox zależnych od pamięci.
[edytuj] Wysyłanie i odbieranie strumieni
Streams are objects that represent URLs and the data they contain. A stream is associated with a specific instance of a plug-in, but a plug-in can have more than one stream per instance. Streams can be produced by the browser and consumed by a plug-in instance, or produced by an instance and consumed by the browser. Each stream has an associated MIME type identifying the format of the data in the stream.
Streams produced by the browser can be automatically sent to the plug-in instance or requested by the plug-in. The plug-in can select one of these transmission modes:
- Normal mode: the browser sends the stream data sequentially to the plug-in as the data becomes available.
- Random-access mode: the browser allows the plug-in to request specific ranges of bytes from anywhere in the stream. This mode requires server support.
- File mode: the browser saves the data to a local file in cache and passes that file path to the plug-in.
Streams produced by the plug-in to send to the browser are like normal-mode streams produced by the browser, but in reverse. In the browser's normal-mode streams, the browser calls the plug-in to inform it that the stream was created and to push more data. In streams produced by the plug-in, by contrast, the plug-in calls Netscape functions to create a stream, push data into it, and delete it.
[edytuj] Praca z adresami URL
The Plug-in API provides methods that plug-ins can use to retrieve data from or post data to a URL anywhere on the network, provide hyperlinks to other documents, post form data to CGI scripts using HTTP, or upload files to a remote server using FTP.
- Use NPN_GetURL to request the browser to load a URL into a particular browser window or frame for display, or to deliver the data of that URL to the plug-in instance in a new stream
- The NPN_GetURLNotify function operates like
NPN_GetURL, except that it notifies the plug-in of the result when the operation completes. - Use NPN_PostURL to send data to a URL from a memory buffer or file. The result from the server can also be sent to a particular browser window or frame for display, or delivered to the plug-in instance in a new stream.
- The NPN_PostURLNotify function operates like
NPN_PostURL, except that it notifies the plug-in of the result when the operation completes.
For information about using these methods, see URL
[edytuj] Pobieranie informacji o wersji i interfejsie użytkownika
The Netscape group of Plug-in API methods provides some basic services to the plug-in. You can use these Netscape methods:
- To identify the browser in which your plug-in is displayed: Use the NPN_UserAgent method to read this information.
- To determine whether plug-in and the browser versions are compatible and possibly provide alternative processing for different versions: Use the NPN_Version method to check for changes in major and minor version numbers.
For information about using these methods, see Version, UI, and Status Information.
[edytuj] Wyświetlanie wiadomości na na pasku statusu
Functionally, your plug-in is seamlessly integrated into the browser and operates as an addition to current browser capabilities. To make the user feel that the plug-in is part of the the browser user interface, your plug-in can emulate the browser behavior by providing status line messages. Use the NPN_Status method to display a message on the status line.
For information about using this method, see Version, UI, and Status Information.
[edytuj] Tworzenie wtyczek skryptowalnych
Scriptable plug-ins are plug-ins that have been extended to provide methods that can be called from JavaScript and the DOM when accessed through the object or embed element. Consider the following example, where a media player plug-in can be controlled with an advanceToNextSong() method called inside the script element:
<object id="myPlugin"
type="audio/wav"
data="music.wav">
</object>
<script type="application/javascript">
var thePlugin = document.getElementById('myPlugin');
if (thePlugin)
thePlugin.advanceToNextSong();
else
alert("Plugin not installed correctly");
</script>
In the past, LiveConnect and later XPConnect were used to make plug-ins scriptable. See the Wikipedia article for historical information. Both technologies are now obsolete for the purposes of plug-in scriptability, and the cross-browser npruntime API should be used instead.
See the Scripting plugins section of this reference for the details.
[edytuj] Kompilowanie wtyczek
Once you have added the special code and additional files to make your plug-in scriptable as described in the previous section, the build process is quite straight-forward. In addition to the DLL that goes in the plugins folder, you must also place a type library and an extra header file in the appropriate places in your application directory. This section describes those extra scriptability steps in more detail.
[edytuj] Kompilacja, Platformy, Kompilatory
Build resources have been supplied with the SDK for all of the major platforms. There are makefiles for the Unix platform, project files for the Windows and Mac OS X IDEs, definition files, resources files, and other resources for building the samples in the SDK and your own plug-in projects. Gecko plug-ins can also be compiled by well-known compilers on all the major platforms - though using those compilers competently is of course outside the scope of this manual.
All the resources you need - the definition files, the source files, the resource files - can be found in the Plug-in SDK, which is available in the mozilla source tree and also as separately downloadable and buildable software kit. The basic plug-in example, located in the mozilla source at modules/plugin/tools/sdk/samples/basic
, has all the files you need to build a simple plug-in on the major platforms.
[edytuj] Kompilowanie wtyczek dla Mac OS X(Carbonized Plug-ins)
The building process for Mac OS X plug-ins is very like that for Mac "classic" plug-ins and plug-ins on other platforms. There are, however, a couple of differences you must be aware of if you are going to successfully compile your plug-in for the Mac OS X platform.
The main change is visible in the npupp.h header file, where the preprocessor variable _NPP_USE_UPP_ is set to FALSE or 0, because TARGET_API_MAC_CARBON is true:
/* NPP_Initialize */
#define _NPUPP_USE_UPP_ (TARGET_RT_MAC_CFM && !TARGET_API_MAC_CARBON)
#if _NPUPP_USE_UPP_
typedef UniversalProcPtr NPP_InitializeUPP;
enum {
uppNPP_InitializeProcInfo = kThinkCStackBased
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0))
| RESULT_SIZE(SIZE_CODE(0))
};
#define NewNPP_InitializeProc(FUNC) \
(NPP_InitializeUPP) NewRoutineDescriptor((ProcPtr)(FUNC),
uppNPP_InitializeProcInfo, GetCurrentArchitecture())
#define CallNPP_InitializeProc(FUNC) \
(void)CallUniversalProc((UniversalProcPtr)(FUNC),uppNPP_InitializeProcInfo)
#else
typedef void (* NP_LOADDS NPP_InitializeUPP)(void);
#define NewNPP_InitializeProc(FUNC) \
((NPP_InitializeUPP) (FUNC))
#define CallNPP_InitializeProc(FUNC) \
(*(FUNC))()
#endif
When this is the case, all of the function pointers in the NPPluginFuncs struct, also described in the npupp.h header file, will be actual function pointers and not "routine descriptors," which aren't supported in the Carbon runtime:
typedef struct _NPPluginFuncs {
uint16 size;
uint16 version;
NPP_NewUPP newp;
NPP_DestroyUPP destroy;
NPP_SetWindowUPP setwindow;
NPP_NewStreamUPP newstream;
NPP_DestroyStreamUPP destroystream;
NPP_StreamAsFileUPP asfile;
NPP_WriteReadyUPP writeready;
NPP_WriteUPP write;
NPP_PrintUPP print;
NPP_HandleEventUPP event;
NPP_URLNotifyUPP urlnotify;
JRIGlobalRef javaClass;
NPP_GetValueUPP getvalue;
NPP_SetValueUPP setvalue;
} NPPluginFuncs;
Finally, in the Mac Classic plug-ins, the main entry point is required to be an exported symbol called "mainRD", which is a routine descriptor for the plug-ins main function:
#ifdef XP_MAC
/******************************************************************************************
* Mac platform-specific plugin glue stuff
*******************************************************************************************/
/*
* Main entry point of the plugin.
* This routine will be called when the plugin is loaded. The function
* tables are passed in and the plugin fills in the NPPluginFuncs table
* and NPPShutdownUPP for Netscape's use.
*/
#if _NPUPP_USE_UPP_
typedef UniversalProcPtr NPP_MainEntryUPP;
enum {
uppNPP_MainEntryProcInfo = kThinkCStackBased
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPNetscapeFuncs*)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPluginFuncs*)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPP_ShutdownUPP*)))
| RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
};
#define NewNPP_MainEntryProc(FUNC) \
(NPP_MainEntryUPP) NewRoutineDescriptor((ProcPtr)(FUNC),
uppNPP_MainEntryProcInfo, GetCurrentArchitecture())
#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \
CallUniversalProc((UniversalProcPtr)(FUNC),
(ProcInfoType)uppNPP_MainEntryProcInfo, (netscapeFunc),
(pluginFunc), (shutdownUPP))
However, in the Carbon runtime plug-ins, it's good form if the plug-in exports a "main" entry point, which is expected to have the same prototype. At a bare minimum, the shared library's "main" entry point must be set to such a routine.
[edytuj] Pobieranie i używanie kompilatora XPIDL
The XPIDL compiler that you must use to create the type library and the header file for your plug-in is a regular product of the mozilla build process. In the bin directory of your mozilla build, you ought to see the xpidl binary. Use the -m option to specify which kind of output you want, as in the following usage note.
Usage: ./xpidl [-m mode] [-w] [-v][-I path] [-o basename | -e filename.ext] filename.idl
-a emit annotations to typelib
-w turn on warnings (recommended)
-v verbose mode (NYI)
-I add entry to start of include path for ``#include "nsIThing.idl"''
-o use basename (e.g. ``/tmp/nsIThing'') for output
-e use explicit output filename
-m specify output mode:
header Generate C++ header (.h)
typelib Generate XPConnect typelib (.xpt)
doc Generate HTML documentation (.html)
java Generate Java interface (.java)
For example, to create a header file for a plug-in IDL file nsITestPlugin.idl, you would type the following at the command prompt:
./xpidl -m header nsITestPlugin.idl
The resulting header file, nsITestPlugin.h, should then be included when the nsTestPlug.dll is built.
[edytuj] Biblioteki typów
In addition to the header file, you must also create a type library file for your plug-in. This file - in our example, nsITestPlugin.xpt - can also easily be generated from the XPIDL compiler, and should be placed in the Plugins subdirectory of the browser application.
The type library is a special binary independent interface file that exposes the interface(s) of an object in a way that allows them to be used uniformly across platforms, languages, and programming environments. The type library provides the information about the interface at run-time, which is required in a cross-platform component framework like XPCOM.
To create a type library file for the nsITestPlugin.idl IDL, you would type the following at the command prompt:
./xpidl -m typelib nsITestPlugin.idl
[edytuj] Instalowanie wtyczek
With the redesign of the Netscape and Mozilla browsers, there has been a dramatic change to the way that plug-ins and other software are installed. Gecko now provides a cross-platform installation API that you can use to install new browser components, plug-ins, applications, or any other software.
You can install your plug-in in one of three ways:
- You can create a small installation script to download and execute a binary installer for the plug-in, as described in the Własne instalatory below.
- Alternatively you can do the entire installation using the
XPInstall API, which is documented in the Instalacja wtyczek za pomocą XPI section below that. For more general information about the XPInstall API, see the Dokumentacja XPInstall API. - An even easier option that works in Firefox 1.5+ is to build an XPI with your plug-in in the plugins folder (see Paczki) and an install.rdf manifest. This method of installation gives you less flexibility, but makes it easy for the user to uninstall the plug-in from the application UI.
[edytuj] Własne instalatory
Plug-ins must use the XPInstall API to install themselves in the appropriate area. They may also use other binary installers, as before, in which case the XPInstall archive and its installation script are effectively a small wrapper for the installer executable, downloading that binary and executing it on the user's system. The following installation script example gives you some idea of how simple this "wrapper" can be.
// DJ Double-Decker Plug-in Installer
err = initInstall("DJ Double-Decker Plug-in Installer", "DJDD", "0.9");
logComment("initInstall() returned: " + err);
err = execute("djdd.exe", "", true);
logComment("execute() returned: " + err);
if(!err)
{
err = performInstall();
logComment("performInstall() returned: " + err);
}
Even with the optional logging (i.e., the logComment() method used after each main step to check the return value of that function), the installation is less than ten lines.
Using an XPInstall script like this to wrap the installer has the additional advantage of running in the same process as the browser, which means that you can invoke the installer executable and hand back control immediately.
initInstall begins every installation script with parameters representing the name and other information about the installation. The next line uses the execute() method (which is a member of the Install object, implicit in installation script just as the window object is implicit in browser scripts) to execute the installer contained within the archive. performInstall() begins the actual installation. Note that you do not have to install the installer in order to execute it on the local system. See the The XPInstall API for more information about cross-platform installations, and see the second example below for a more detailed plug-in installation, in which the XPInstall API performs all of the necessary steps to install the plug-in and its supporting files and register it with the browser.
This script is included in a special archive called a XPI. When a separate executable is performing the actual installation, the contents of that XPI may be nothing other than the installer executable and the install.js installation script.
[edytuj] Instalacja wtyczek za pomocą XPI
You can also use the XPInstall API do the installation yourself, without using a third-party installer. The following script works on any platform, and installs the JRE 1.3 plug-in the JRE in the Netscape 6 browser. This sort of script can easily be adapted to install any type of plug-in.
// this function verifies disk space in kilobytes
function verifyDiskSpace(dirPath, spaceRequired)
{
var spaceAvailable;
// Get the available disk space on the given path
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
// Convert the available disk space into kilobytes
spaceAvailable = parseInt(spaceAvailable / 1024);
// do the verification
if(spaceAvailable < spaceRequired)
{
logComment("Insufficient disk space: " + dirPath);
logComment(" required : " + spaceRequired + " K");
logComment(" available: " + spaceAvailable + " K");
return(false);
}
return(true);
}
var srDest = 38628;
var err = initInstall("Sun Java 2", "/Sun/Java2", "1.3");
logComment("initInstall: " + err);
var fPlugins= getFolder("Plugins");
logComment("plugins folder: " + fPlugins);
if (verifyDiskSpace(fPlugins, srDest))
{
err = addDirectory("JRE_Plugin_Linux_i386",
"1.3",
"jre-image-i386", // jar source folder
fPlugins, // target folder
"java2", // target subdir
true ); // force flag
logComment("addDirectory() returned: " + err);
// create symlink: plugins/libjavaplugin_oji.so ->
// plugins/java2/plugin/i386/libjavaplugin_oji.so
var lnk = fPlugins + "libjavaplugin_oji.so";
var tgt = fPlugins + "java2/plugin/i386/ns600/libjavaplugin_oji.so";
var ignoreErr = execute("symlink.sh", tgt + " " + lnk, true);
logComment("execute symlink.sh "+tgt+" "+lnk+" returned: "+ignoreErr);
if (err==SUCCESS)
{
err = performInstall();
logComment("performInstall() returned: " + err);
}
else
{
cancelInstall(err);
logComment("cancelInstall() returned: " + err);
}
}
else
cancelInstall(INSUFFICIENT_DISK_SPACE);
Note that this script installs the Linux JRE plug-in and assumes you are running Linux, but you can also use the The XPInstall API to check the platform type, check for the presence of other files, and perform other preparatory functions in your installation scripts.
Also note the use of the "Plugins" keyword in the getFolder() function to locate and specify the plug-ins subdirectory in a cross-platform way. The returned object, fPlugins, is used as the target folder for installation of this binary file in the addDirectory() function that actually specifies where the files in the XPI are to be installed on the local machine.
[edytuj] Instalacja wtyczek a rejestr Windows
An important aspect of the installation process on the Windows platform is the reading of registry keys to determine how many Gecko-based browsers are installed locally, which they are, and how they are configured for plug-ins.
Whether you are using a native Windows installer like InstallShield or writing installation scripts using the The XPInstall API (see "Instalacja wtyczek za pomocą XPI"), you can access the registry, read and write data about your plug-in, and customize your installation for the different Gecko installation targets, as this section describes.
The registry keys that affect the installation of plug-ins are subkeys of the various Gecko-based products enumerated under:
HKEY_LOCAL_MACHINE\Software\Mozilla
The products are listed as subkeys of the Mozilla key. You can enumerate these subkeys to get the Gecko-based browsers, and further enumerate those subkeys to read such important configuration information as where in the browser application directories the plug-in should be installed, which version is installed, and so on.
The Plugins key-value pair shows where plug-ins should be installed for that Gecko-based product:
Plugins = C:\Program Files\Mozilla Firefox\plugins
For all but the newest Gecko-based products, the Components key-value pair also holds an important piece of information: As described in the "Type Libraries" section above, Gecko-based products require that you put the type library file, or XPT, in the Components subdirectory.
Components = C:\Program Files\Mozilla Firefox\components
Also, the product subkey (e.g., Mozilla/Mozilla Firefox 2.0.0.1) has a bin subkey which exposes the PathToExe key-value pair:
PathToExe = C:\Program Files\Mozilla Firefox\firefox.exe
See the XPInstall registry manipulation example for more information about how these key values from the registry can be used to steer your installation for different targets.
If you are using a native installer, then that installer will have its own way to access and update the registry. If you are using the XPInstall API, then you can use the winReg function to find the plug-in subdirectories where your software should be installed, as the following example demonstrates.
var winreg = getWinRegistry();
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
var index = 0;
var baseKey = "Software\\Mozilla";
while ( (MozillaVersion = winreg.enumKeys(baseKey,index)) != null )
{
logComment("MozillaVersion = " + MozillaVersion);
subkey = baseKey + "\\" + MozillaVersion + "\\Extensions";
pluginsDir = winreg.getValueString ( subkey, "Plugins" );
if ( pluginsDir )
logComment("pluginsDir = " + pluginsDir);
else
logComment("No plugins dir for " + baseKey + "\\" + MozillaVersion);
index++;
}
When combined with the installation examples above, this kind of parsing of the Windows registry can make it easy for you to install plug-ins on different platforms and browsers.