Anyway, some background: basically what I'm trying to do is to explore the set of components made available by the XPCOM runtime. So first I iterate over all the contract IDs as the code I posted demonstrates. Of course, that's only the first step.
But even if I ignore the error described in my last post, I get a different problem in the next step: I want to get the list of interfaces implemented by each of the components, using nsIClassInfo. Stripped down code:
void cmpdump(const char *contractID) {
printf(" + %s\n", contractID);
nsCOMPtr<nsIComponentManager> cmpmgr;
NS_GetComponentManager(getter_AddRefs(cmpmgr));
nsCOMPtr<nsISupports> supports;
cmpmgr->GetClassObjectByContractID(contractID,
NS_GET_IID(nsISupports), getter_AddRefs(supports));
nsCOMPtr<nsIClassInfo> classInfo(do_QueryInterface(supports));
if (classInfo) {
PRUint32 numInterfaces;
nsIID **iids = nsnull;
classInfo->GetInterfaces(&numInterfaces, &iids);
for (int i = 0; i < numInterfaces; i++) {
printf(" - %s\n", iids[i]->ToString());
}
}
}For most of the components, I can successfully QueryInterface() to the nsIClassInfo interface, and the GetInterfaces() call succeeds. However, the array returned is always empty (array is NULL, size_is is 0)! Are there any requirements for getting nsIClassInfo to work that I might be missing here?
If it is of any help, this is a command-line test application compiled against a debug build of the Mozilla 1.7b source.
Any hints would be very much appreciated!
Cheers, Chris
Christopher Lenz wrote:
Hi folks,
I'm trying to get a list of all components registered with the XPCOM runtime. I'm using nsIComponentRegistrar::EnumeratorContractIDs for that, but am having a weird problem: while it seems that all contract IDs are returned, at one point the GetNext() call to the enumerator fails even though the HasMoreElements() call returned TRUE.
Here's a stripped down test case that shows the problem:
---------------------------------------------------------------- #include "mozilla-config.h" #include "nsCOMPtr.h" #include "nsIComponentRegistrar.h" #include "nsIServiceManager.h" #include "nsISimpleEnumerator.h" #include "nsISupportsPrimitives.h" #include "nsString.h" #include "nsXPCOM.h"
void regdump() { nsCOMPtr<nsIComponentRegistrar> registrar; NS_GetComponentRegistrar(getter_AddRefs(registrar)); nsCOMPtr<nsISimpleEnumerator> enumerator; registrar->EnumerateContractIDs(getter_AddRefs(enumerator)); PRBool more = PR_FALSE; enumerator->HasMoreElements(&more); while (more == PR_TRUE) { nsCOMPtr<nsISupports> element; nsresult rv = enumerator->GetNext(getter_AddRefs(element)); if (NS_FAILED(rv)) { printf("Failed to get next contract ID from enum!\n"); break; } nsCOMPtr<nsISupportsCString> contractId( do_QueryInterface(element)); nsCAutoString str; contractId->GetData(str); printf("%s\n", PromiseFlatCString(str).get()); enumerator->HasMoreElements(&more); } }
int main(int argc, char* argv[]) { nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) { return -1; } regdump(); rv = NS_ShutdownXPCOM(nsnull); if (NS_FAILED(rv)) { return -1; } return 0; } ----------------------------------------------------------------
I've tested this code (well, similar code) on both Win2K and MacOSX, with both Mozilla 1.6 and Mozilla 1.7b, and using both debug and non-debug builds. The failure is always reproducible.
Without specifing a bin directory for XPCOM, the failure appears when trying to get the 48th component. When I specify the bin dir, I get many more components before the enumeration fails. That's why I suspect the list I get is actually complete, but the simple enumerator fails to tell me so.
The same happens for nsIComponentRegistrar::EnumerateCIDs() BTW.
I must be doing something incredibly stupid :-P Can anyone point out what it is?
Cheers, Chris
_______________________________________________ Mozilla-xpcom mailing list [EMAIL PROTECTED] http://mail.mozilla.org/listinfo/mozilla-xpcom
