Reported by jteh on 2010-08-24 01:08
Some Handy Tech displays now implement the USB HID device class, which means that they don't require USB drivers to be installed. However, NVDA currently requires the Handy Tech COM server to be installed on the system, which breaks the portability afforded by the use of HID. NVDA should bundle the COM server so that these displays can be used without any installation.
Because it is a COM server, it needs to be registered with the system. This can be done using application manifests. I'd prefer to avoid modifying NVDA's manifest if possible. An option that needs to be explored is to use activation contexts to register a manifest at runtime. Failing this, we do want the feature, so modifying our application manifest is acceptable if it is the only way.
The text was updated successfully, but these errors were encountered:
Comment 2 by bramd on 2010-12-19 18:20
I would like to have a look at this. Did you already try to modify the manifest at runtime or do you have some starting points? If not, I'll just start researching myself.
Comment 3 by jteh (in reply to comment 2) on 2010-12-20 01:40
Replying to bramd:
I would like to have a look at this. Did you already try to modify the manifest at runtime or do you have some starting points?
Haven't tried yet myself. However, my research suggests that a manifest can be loaded at runtime using activation contexts. See Activation Context Reference in MSDN for details. I think the steps would be something like this:
Call !CreateActCtx(), passing it a pointer to an ACTCTX structure which references the required manifest.
Call !ActivateActCtx() with the handle returned in step 1.
Initialise the Handy Tech COM object.
Use !DeactivateActCtx() to deactivate the context which was activated in step 2.
Things I'm not sure about:
Do you have to wait until the COM object is released before calling !DeactivateActCtx()? I doubt it, but am not certain.
Does !DeactivateActCtx() free the activation context or do you have to call !ReleaseActCtx() as well?
Comment 4 by jteh on 2011-01-14 07:56
I tried using activation contexts, but unfortunately, it doesn't work properly. I had the same problem as with retrieving the class factory from the dll and creating an instance using that: we can execute methods on the Handy Tech server and they work just fine, but we never receive events. I suspect this is because although everything has been registered in our thread thanks to the activation context, perhaps the Handy Tech server uses another thread for events, in which case the registration wouldn't occur in that other thread. The way the Handy Tech COM server works is a bit strange; for a start, it doesn't embed the typelib in the dll and I'm not sure why, although I suspect this may be part of the problem.
In any case, it looks like the only solution is to embed this in our application manifest. We can't just override our manifest statically, as we need the UAC info to be dynamically configurable. From memory, this will require us to tweak py2exe somewhat, as I don't think it allows arbitrary chunks to be included in the manifest.
Comment 5 by jteh (in reply to comment 4) on 2011-01-19 07:44
Replying to jteh:
it looks like the only solution is to embed this in our application manifest. We can't just override our manifest statically, as we need the UAC info to be dynamically configurable. From memory, this will require us to tweak py2exe somewhat, as I don't think it allows arbitrary chunks to be included in the manifest.
I've figured out how to do this. I've tested it and it does work. We need to make sure the dll doesn't get loaded unless it is actually needed and a few other details.