发布时间:2011-3-30 10:37
分类名称:Plugins
原文链接:http://nerdlife.net/building-a-c-xpcom-component-in-windows/
I’ve been teaching myself to write Firefox extensions for the last few weeks, and became interested in XPCOM components. Unfortunately, I couldn’t find a good (and recent) summary of them, and had to spend 3 or 4 days cobbling together various tutorials, so I figured it’s time to write one.
XPCOM is a language-agnostic communication platform used in Mozilla products (and some other random pieces of software) to allow code (specifically extensions) to be written in a wide variety of languages.
There are two ways to “use” XPCOM. First, you can call functions through XPCOM. For example, the Firefox bookmarks service uses an XPCOM interface. So in order to interact with this service from Javascript you would do something like:
var bmarks = Components.classes["@mozilla.org/browser/bookmarks-service;1"].getService(); bmarks.QueryInterface(Components.interfaces.nsIBookmarksService); bmarks.addBookmarkImmediately("http://www.mozilla.org","Mozilla",0,null);
There are plenty of tutorials on doing this as it is the more common use for XPCOM, so I won’t go into any detail on it here.
The second way is to write an XPCOM service. That is what this tutorial covers. Sometimes you need extra functionality, speed, or just want to tie into some library that requires a different language. Most commonly this is C++, but there is also JavaXPCOMand PyXPCOM (and probably a few others). I’ll be talking about C++, since it’s what I needed for my project.
If you don’t want to go through the tutorial and just want everything to work, then download this sample code. Just follow step #1 of the tutorial, then make sure your Gecko SDK directory is set right in the build step, and you can breeze on by most of this article.
This is mostly paraphrased from Alex Sirota’s great tutorial, but it hasn’t been updated since 2005 and is a bit outdated. This new one should work out of the box for FF 3.6.
This tutorial will create a component called MyComponent
with one function: Add
, which will take 2 numbers and, surprisingly, return the sum.
IMyComponent.idl
, with the following (replacing ***IUID***
with your interface UUID):#include "nsISupports.idl" [scriptable, uuid(***IUID***)] interface IMyComponent : nsISupports { long Add(in long a, in long b); };
This file is a language-agnostic interface definition which you can read more abouthere.
C:\xulrunner-sdk\
, run the following commands (from the directory you saved IMyComponent.idl
to):C:\xulrunner-sdk\sdk\bin\xpidl.exe -m header -I C:\xulrunner-sdk\idl .\IMyComponent.idl C:\xulrunner-sdk\sdk\bin\xpidl.exe -m typelib -I C:\xulrunner-sdk\idl .\IMyComponent.idl
These will create IMyComponent.h
and IMyComponent.xpt,
respectively.
IMyComponent.h
has two snippits of code that you can use for the next two files. Everything between /* Header file */
and /* Implementation file */
can be used for MyComponent.h
:#ifndef _MY_COMPONENT_H_ #define _MY_COMPONENT_H_ #include "IMyComponent.h"
#define MY_COMPONENT_CONTRACTID "@example.com/XPCOMSample/MyComponent;1" #define MY_COMPONENT_CLASSNAME "A Simple XPCOM Sample" #define MY_COMPONENT_CID ***CUID***
IMyComponent.h
, replacing all the instances of _MYCLASS_
with the name of your component (MyComponent
).#endif //_MY_COMPONENT_H_
/* Implementation file */
and /* End of implementation class template. */
can be used for MyComponent.cpp
:#include "MyComponent.h"
IMyComponent.h
, replacing all the instances of _MYCLASS_
with the name of your component (MyComponent
).Add
method. I replaced return NS_ERROR_NOT_IMPLEMENTED;
with*_retval = a + b; return NS_OK;
#include "nsIGenericFactory.h" #include "MyComponent.h" NS_GENERIC_FACTORY_CONSTRUCTOR(MyComponent) static nsModuleComponentInfo components[] = { { MY_COMPONENT_CLASSNAME, MY_COMPONENT_CID, MY_COMPONENT_CONTRACTID, MyComponentConstructor, } }; NS_IMPL_NSGETMODULE("MyComponentsModule", components)
You now have all of the files needed to build an XPCOM component:
IMyComponent.h IMyComponent.idl IMyComponent.xpt MyComponent.cpp MyComponent.h MyComponentModule.cpp
Now comes the hard part: getting the damn thing to build.
Ok, it’s actually not hard since I’ve done most of the legwork for you. Assuming you’re using Visual C++ 2008 here are the settings you need (again assuming C:\xulrunner-sdk
is where your Gecko SDK is). In Project->Properties
:
Configuration Properties General Configuration Type: .dll C/C++ General Additional Include Directories: C:\xulrunner-sdk\include Preprocessor Preprocessor Definitions: XP_WIN;XP_WIN32;XPCOM_GLUE_USE_NSPR Linker General Additional Library Directories: C:\xulrunner-sdk\lib Input Additional Dependencies: nspr4.lib xpcom.lib xpcomglue_s.lib
If you put the idl file into your project, be sure to mark it “Excluded from Build” in its properties…we don’t want VS touching it.
Cross your fingers, pray to whatever deity you believe in, and hit the build button. If it didn’t work let me know why in the comments and I’ll try to build a troubleshooting section.
C:\Program Files\Mozilla Firefox\components
:IMyComponent.xpt
xpti.dat.
and compreg.dat
from your profile directory (FF will regenerate them on next restart)MyComponentTest.html
in the sample code):<html> <script type="text/javascript"> function MyComponentTestGo() { try { // normally Firefox extensions implicitly have XPCOM privileges, but since this is a file we have to request it. netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); const cid = "@example.com/XPCOMSample/MyComponent;1"; obj = Components.classes[cid].createInstance(); // bind the instance we just created to our interface obj = obj.QueryInterface(Components.interfaces.IMyComponent); } catch (err) { alert(err); return; } var res = obj.Add(3, 4); alert('Performing 3+4. Returned ' + res + '.'); } </script> <body> <button >Go</button> </body> </html>
Hopefully this clears up what looked like a lot of confusion to me. I will keep this updated to the best of my abilities and hopefully it will continue to be useful for a long time.
================================================================================
Some more warnings might be appropriate –
#3 – If you just got here from a search engine and this is your first time on the site, take note. Brian is extremely good at what he does, and while he doesn’t really make this sound easy, it’s still harder than it looks. The guy worked for Mozilla (admittedly not on this) and does webdev professionally. My point is, just keep in mind that getting XPCOM to work is absolutely nontrivial.
#4 – If you’re trying to get XPCOM to work on OS X… well, honestly, you should really try to think about another way of accomplishing your goal. Before I committed to compiling an XPCOM component on a Mac, I would wait and see if ctypes magically solved all of my problems.
TL;DR – its harder than it looks.
Hello,
Thanks, I compiled it on linux with the makefile at the end of this page:
http://groups.google.fr/group/mozilla.dev.tech.xpcom/tree/browse_frm/month/2008-12/58e0638e17596c16?rnum=1&_done=%2Fgroup%2Fmozilla.dev.tech.xpcom%2Fbrowse_frm%2Fmonth%2F2008-12%3F
I ontained a “.so”
I did all the end of the procedure but when I went on the htmlpage and I click on the button I get :
“TypeError: Components.classes[cid] is undefined”
so bad for me…
I have firefox 3.5.8, i have compiled with sdk 1.9.1.7 and 1.9.2, same result…
@gil: Did you copy the .xpt file and the .so file into the right folder? That error means that it’s not actually loading your component, so either you’re referencing the component wrong (wrong name), it didn’t build correctly, or you didn’t put it in the right place.
Let me know if that helps.
Yes I put them in good directory, (delete xpti.dat and compreg.dat)
when restart Firefox, in tools–>error concsole, I’ve got this 3 errors :
“Failed to load XPCOM component: /usr/lib/firefox-3.5.8/components/MyComponent.so”
“Failed to load XPCOM component: /usr/lib/xulrunner-1.9.1.8/components/pyabout.py”
“Failed to load XPCOM component: /usr/lib/xulrunner-1.9.1.8/components/py_test_component.py”
I’ve tried too an install with the xpi method and it looks similar errors in the console…
I make an install.rdf and a folder “components” that include the “.so” and the “.xpt”,then I pack them all in a “xpi”, is it equivalent to the first method?
I’ve tested your tuto on windows and it works very well, thanks !
even with the xpi method
the problem is only on linux, so pgerhaps because I am on FF 3.5.8 on linux or my compilation script isn’t good…
I’ll continue to devellop on windows waiting to find a solution on linux
here’s the result of the command :
./run-mozilla.sh `which ldd` -r /usr/lib/firefox-3.5.8/components/MyComponent.so
undefined symbol: _Z16NS_TableDrivenQIPvPK12QITableEntryRK4nsIDPS_ (/usr/lib/firefox-3.5.8/components/MyComponent.so)
undefined symbol: _Z20NS_NewGenericModule2PK12nsModuleInfoPP9nsIModule (/usr/lib/firefox-3.5.8/components/MyComponent.so)
linux-gate.so.1 => (0×00d85000)
libnspr4.so => /usr/lib/libnspr4.so (0×00f94000)
libplds4.so => /usr/lib/libplds4.so (0×00e17000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0×00110000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0×00546000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0×00a8c000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0×00612000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0×0099a000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0×00ec5000)
/lib/ld-linux.so.2 (0×00225000)
Well,man. I did exactly what you guided above. Firstly, the errors come with some kind of missing nsISupports.idl and nsrootidl.idl. Then I copied those two into the same directory with my project. Another error came up saying that: “error MIDL2025 : syntax error : expecting an interface name or DispatchInterfaceName or CoclassName or ModuleName or LibraryName or a type specification near “%” “.
What is going on here?
Thank in advance.
Is there any other way, aside from putting most of my code in a DLL using this method, of writing a FF xtn that cannot be read openly by anyone?
I want to write a commercial extension (ie it will be sold), but doing it in Javascript means anyone who buys it can copy the code, change it up a bit, and sell it as a competitor.
I understand FF isn’t really set up as a platform for selling extensions (a whole debate in itself), but is there some way round this?
Hello,
Does anyone solve the problem with undefined cid?
I’ve notice that in file MyComponent.h is cid defined as “@mydomain.com/XPCOMSample/MyComponent;1″, but script in test page is calling other cid “@example.com/XPCOMSample/MyComponent;1″
But even changing cid to righ value, doesn’t solve the problem.
Well, I’ll take a closer look at these CID’s and send repot if succeed.
Hi, I’ve tried many times to launch my component, but it’s still failed. I’ve theses errors in my error console :
Failed to load XPCOM component: C:\Users\Sahbi\AppData\Roaming\Mozilla\Firefox\Profiles\mk4oj57p.default\extensions\{DDC359D1-844A-42a7-9AA1-88A850A938A8}\components\contenthandling.idl
Failed to load XPCOM component: C:\Users\Sahbi\AppData\Roaming\Mozilla\Firefox\Profiles\mk4oj57p.default\extensions\{DDC359D1-844A-42a7-9AA1-88A850A938A8}\components\debugService.idl
Failed to load XPCOM component: C:\Users\Sahbi\AppData\Roaming\Mozilla\Firefox\Profiles\mk4oj57p.default\extensions\{DDC359D1-844A-42a7-9AA1-88A850A938A8}\components\filterManager.idl
I’ve placed the two files (.dll and .xpt) in the right folder so i do not understand
Hi,
I downloaded the example and built it using VS2008 on Vista. I am running firefox 3.6.3 and xul-runner sdk 1.9.2. I deployed the DLL and XPT file to the firefox components directory and deleted the xpti.dat and compreg.dat files. I got the dreaded “TypeError: Components.classes[cid] is undefined” error.
I tried using dependency walker and it doesn’t look like firefox is even attempting to load the dll (can’t find any mention in the logs). I think that I must have something fundamental wrong… but don’t know what it is. Are there any articles on the loading process and any tools that help to debug it?
Hi,
Well after some research and testing I found out these things:
- make project exactly as in tutorial
- use only one CID for all occurence in files (in MyComponent.h is wrong
CID). Here is nice generator for CID
http://mozilla.pettay.fi/cgi-bin/mozuuid.pl
- when deleting files compreg.dat and xpti.dat I modify components.list
(same location where you put DLL and XPT files) and add at the end of
file “MyComponent.dll”.
After all it worked
Other, probably better way, to solve problem with undefined cid is to register new component with regxpcom.exe.
From Mozilla Developer Center:
“The regxpcom Program
An explicit way to register a component is to run the application regxpcom. Without any arguments passed to regxpcom, the program registers the component in the default component registry. We suggest that when you are testing your component in the Mozilla or Netscape client, you copy your component into the components directory in the client’s installation folder. When it is copied there, run regxpcom from the command line to register that component and all the others in that directory. ”
regxpcom should be located in same dir as mozcrt19.dll
for me it’s C:\Program Files\Mozilla Firefox\
Hope this will help
Hi, i’ve also the “TypeError: Components.classes[cid] is undefined” error… I’ve tried the two ways you talked about Miro, but it didn’t work. Even with regxpcom.exe.
I’ve tried to verify the CID, I generated again the files with xpidl.exe and build the .dll but it still did not work. I’ve always the same error. Even if I used the sample code given above, this doesn’t work.
Could it be a problem if my FF version is 3.6.3 and xul-runner 9.1.2 ?
Please, if someone could help
Hello,
I’ve tried make project again, but this time with some changed class names and slightly different interface definition. Visual C++ didn’t even compile. This is VC++ output:
TestMachine.cpp
Generating Code…
Skipping… (no relevant changes detected)
TestMachineModule.cpp
Linking…
Creating library C:\Users\miro\Desktop\XUL\project\TestMachine\Debug\TestMachine.lib and object C:\Users\miro\Desktop\XUL\project\TestMachine\Debug\TestMachine.exp
TestMachine.obj : error LNK2019: unresolved external symbol __imp__NS_LogAddRef referenced in function “public: virtual unsigned long __stdcall TestMachine::AddRef(void)” (?AddRef@TestMachine@@UAGKXZ)
TestMachine.obj : error LNK2019: unresolved external symbol __imp__PR_GetCurrentThread referenced in function “public: virtual unsigned long __stdcall TestMachine::AddRef(void)” (?AddRef@TestMachine@@UAGKXZ)
TestMachine.obj : error LNK2019: unresolved external symbol __imp__NS_DebugBreak referenced in function “public: virtual unsigned long __stdcall TestMachine::AddRef(void)” (?AddRef@TestMachine@@UAGKXZ)
TestMachine.obj : error LNK2019: unresolved external symbol __imp__NS_LogRelease referenced in function “public: virtual unsigned long __stdcall TestMachine::Release(void)” (?Release@TestMachine@@UAGKXZ)
TestMachine.obj : error LNK2019: unresolved external symbol “unsigned int __fastcall NS_TableDrivenQI(void *,struct QITableEntry const *,struct nsID const &,void * *)” (?NS_TableDrivenQI@@YIIPAXPBUQITableEntry@@ABUnsID@@PAPAX@Z) referenced in function “public: virtual unsigned int __stdcall TestMachine::QueryInterface(struct nsID const &,void * *)” (?QueryInterface@TestMachine@@UAGIABUnsID@@PAPAX@Z)
TestMachineModule.obj : error LNK2019: unresolved external symbol “unsigned int __cdecl NS_NewGenericModule2(struct nsModuleInfo const *,class nsIModule * *)” (?NS_NewGenericModule2@@YAIPBUnsModuleInfo@@PAPAVnsIModule@@@Z) referenced in function _NSGetModule
C:\Users\miro\Desktop\XUL\project\TestMachine\Debug\TestMachine.dll : fatal error LNK1120: 6 unresolved externals
Well apparently is something wrong with definitions made by macros in code. Or maybe with linking, dependencies or alike things.
But compiling downloaded .vcproj is fine.
Anybody has similar problem, or has already solve?
To Brian:
How did you exactly make this VC project?
Hi,
I’m writing a xpcom extension and i used your tutorial to build the xpcom component. It works fine on my computer but when I try to install this extension somewhere else than my development environment it’s not working any more (“TypeError: Components.classes[cid] is undefined”).
I also built an extension only for testing with your project file and it’s the same result.
Any ideas?
I’m using WinXP, Visual Express 2010, Firefox 3.6.3 and Gecko 1.9.2.
see also: http://forums.mozillazine.org/viewtopic.php?f=19&t=1865365
thanks!
/Stefan
(btw, really great tutorial. good structure and easy to understand)
Dude thanks a lot for this, you have made my day, This was really helpful! I can not express how many howers i lost on this because of the old components that do not compile with the new xul-runner!
class NS_NO_VTABLE NS_SCRIPTABLE IMyComponent : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(IMYCOMPONENT_IID)
/* long Add (in long a, in long b); */
NS_IMETHOD Add(PRInt32 a, PRInt32 b, PRInt32 *_retval) = 0;
};
tanks and keep with the good work
Hi, i’ve also the “TypeError: Components.classes[cid] is undefined” error… I’ve tried the two ways you talked about Miro, but it didn’t work. Even with regxpcom.exe.
I’ve tried to verify the CID, I generated again the files with xpidl.exe and build the .dll but it still did not work. I’ve always the same error. Even if I used the sample code given above, this doesn’t work.
Could it be a problem if my FF version is 3.6.3 and gecko-sdk1.7 ?
Please, if someone could help
@vetrivel r: You absolutely need to use a matching XULRunner version for your FF install. https://developer.mozilla.org/en/gecko_sdk#Downloading
Hi, I follow all recomendation but still have Linking error, can anyone hemp me?
xpcomglue_s.lib(nsCOMPtr.obj) : warning LNK4099: PDB ‘generated.pdb’ was not found with ‘C:\Documents and Settings\***\Bureau\FirefoxPlugin\xulrunner-sdk\lib\xpcomglue_s.lib’ or at ‘c:\documents and settings\***\bureau\xpcom\release\generated.pdb’; linking object as if no debug info
1>xpcomglue_s.lib(nsComponentManagerUtils.obj) : warning LNK4099: PDB ‘generated.pdb’ was not found with ‘C:\Documents and Settings\***\Bureau\FirefoxPlugin\xulrunner-sdk\lib\xpcomglue_s.lib’ or at ‘c:\documents and settings\***\bureau\xpcom\release\generated.pdb’; linking object as if no debug info
1>xpcomglue_s.lib(nsISupportsImpl.obj) : warning LNK4099: PDB ‘generated.pdb’ was not found with ‘C:\Documents and Settings\***\Bureau\FirefoxPlugin\xulrunner-sdk\lib\xpcomglue_s.lib’ or at ‘c:\documents and settings\***\bureau\xpcom\release\generated.pdb’; linking object as if no debug info
1>xpcomglue_s.lib(nsMemory.obj) : warning LNK4099: PDB ‘generated.pdb’ was not found with ‘C:\Documents and Settings\***\Bureau\FirefoxPlugin\xulrunner-sdk\lib\xpcomglue_s.lib’ or at ‘c:\documents and settings\***\bureau\xpcom\release\generated.pdb’; linking object as if no debug info
1>xpcomglue_s.lib(nsGenericFactory.obj) : warning LNK4099: PDB ‘generated.pdb’ was not found with ‘C:\Documents and Settings\***\Bureau\FirefoxPlugin\xulrunner-sdk\lib\xpcomglue_s.lib’ or at ‘c:\documents and settings\***\bureau\xpcom\release\generated.pdb’; linking object as if no debug info
Hi Brian Krausz!
1) I have firefox 3.6.3
2) Download the Gecko SDK:
http://releases.mozilla.org/pub/mozilla.org/xulrunner/releases/1.9.2/sdk/xulrunner-1.9.2.en-US.win32.sdk.zip
3) I download your code:
http://nerdlife.net/wp-content/uploads/2010/02/mycomponent.zip
4) And compile your code
5) Close firefox, Delete xpti.dat. and compreg.dat
6) But i have error “TypeError: Components.classes[cid] is undefined” too
Very strange !!!!
I publish my full code + SDK
xulrunner-sdk_AND_MyComponent.zip
http://www.mediafire.com/download.php?tdnmz0dijyt
or
http://rapidshare.com/files/400335658/xulrunner-sdk_AND_MyComponent.zip.html
Brian !!!!!
I have big request to You !!!!
Can you download file and test XPCOM in your computer ?
Install DLL+XPT and test in your firefox.
Mayby is error in compile time ? And DLL is wrong ??
Hello i found a way to register your component – in %ProgramFiles%\Mozilla Firefox\components there is a file named “componets.list”. Just simply add name of your dll file, this will force the registration (remember to delete compreg.dat from your profile directory before staring firefox.exe).
NOTE: this is valid for Firefox 3.6.3 and gecko 1.9.3. Probably in next relases you will have to care about registration changes –https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_1.9.3
Miro’s suggestion of editing the components.list file is what did the trick for me. Running regxpcom as various tutorials suggest did not add my component to the components.list, but maybe I did something wrong there. In trying to figure out why I needed to use components.list, I found the following, very useful discussions:
http://blog.vlad1.com/2009/10/23/firefox-application-directory-lockdown/
https://developer.mozilla.org/en/Migrating_raw_components_to_add-ons
Basically, as of Firefox 3.6, Mozilla is actively trying to keep developers from dumping their XPCOM components into the default components directory. I’m brand new to extension development, but my current take is that modifying components.list and using the default components directory is still a good way to get yourself going (there are enough moving parts as it is to get in order to get yourself up and running), but once up and running, you should migrate your raw component to an add-on, as the second article discusses.
@Miro
Thank you very much! I tried to compile some XPCOM component for some days. I’ve read many articles for novices with similar sample projects.
By the way. There is another yet CID that should be changed. I mean
const cid = “@mydomain.com/XPCOMSample/MyComponent;1″;
in MyComponentTest.html. It should be the same as in MyComponent.h
#define MY_COMPONENT_CONTRACTID “@mydomain.com/XPCOMSample/MyComponent;1″
how to display the string value in xpcom component in mac .i have written the component that will work for both windows and linux..
I have taken the example from
https://developer.mozilla.org/en/how_to_build_a_binary_xpcom_component_using_visual_studio
Can anyone please reply me ASAP.
thanks in advance ..
Can anybody know how to display string in xpcom component for MAC PC 10.4 version.i have tried from so many tutorial and example but nothing going to be worked ..i need a help to resolve this issue..i have tried the same example
https://developer.mozilla.org/en/how_to_build_a_binary_xpcom_component_using_visual_studiowhich has worked in both Linux and windows ..
the addition of the 2 number i can able to display in MAC PC but cannot able to display string …
can Anybody tell what was wrong so that it is not displaying string.i have downloaded the GEcko-Sdk 1.9.2 for MACi386 fromhttps://developer.mozilla.org/en/gecko_sdk ..
Can anyone please reply me ASAP.
thanks in advance ..
I tried to use %ProgramFiles%\Mozilla Firefox\components there is a file named “componets.list” to register component. But it can not help. FiteFox 3.6.8 doesn’t see my component. Then I increased BuildID in ProgramFiles%\Mozilla Firefox\application.ini, and FF recognised component
Like many others I arrived here because of the following error:
“TypeError: Components.classes[cid] is undefined”
Brian’s tutorial is great but don’t use his sample code as a shortcut because there is a match error in the CONTRACT/CIDs. From his zipped and downloadable source:
In MyComponent.h it’s defined as follows:
#define MY_COMPONENT_CONTRACTID “@mydomain.com/XPCOMSample/MyComponent;1″
In MyComponentTest.html it’s defined as:
const cid = “@example.com/XPCOMSample/MyComponent;1″;
Follow his tutorial though and it works great!
Martin.
Fixed: “TypeError: Components.classes[cid] is undefined”
I was a bit premature with the ’success’ note above and wanted to share a bit more info:
Even after following the tutorial to the letter, I got the same “TypeError: Components.classes[cid] is undefined”. However, after another day of trying, I solved the problem by reverting to xulrunner-1.8.0.4. The xpidl.exe which is part of that xulrunner is significantly smaller than the newer 1.9.2.
So, my setup was as Brian’s, except for the gecko-sdk.
I sure hope things get easier with FF4!
I wish to thank you for this tutorial, Brian, and in particular for the comment about using ctypes instead. I’ve been working on an update of my extension for Firefox 4 (beta 7) recently, and instead of reworking my XPCOM component to be compatible, I chose to use ctypes, which is finally mature enough to do elaborate Windows API calls. It really is easier than XPCOM in C++: far less boilerplate code, plus you get all the benefits of working with an interpreted language like JS (no recompiling etc.)