Problem debugging shell extension in Vista (IShellFolder) - windows

I have created a Windows Shell Extension using ATL (Visual Studio 2008). It has the following modules and each module is a separate ATL Simple Object with its own .rgs file for registration:-
IShellFolder/IShellView -> For a virtual drive in windows explorer
IContextMenu/IShellExtInit -> For a popup menu files and folders
IShellIconOverlayIdentifier - To display overlay icons on files and folders
IShellPropSheetExt/IShellExtInit -> For a custom property page in File & Folder's properties
The above work fine in WinXP and I am able to debug this shell extension in WinXP. But a soon as I switch to Vista, I only get method calls for (2) and (4). The drive gets created in Windows Explorer but the underlying methods are not called when I click it.
Although when I right click I get called for (2) and when I select "Properties" for a file or folder I get into the code for (4).
Is there some interface that I am missing for (1) and (3) on Vista. I could not find full and detailed documentation on writing Shell Extensions for Vista on MSDN. I had already gone through the CodeProject articles on shell extensions.

The problem was because of a Xml SMART Pointer usage. It was has problems when Release() was called on it.
Check this link
Internet Explorer crashes when MSXML2::IXMLDOMDocumentPtr -> Release() is called

Make sure that your extensions are handling the initialization properly, otherwise the verclsid.exe won't let your extension getting loaded.
verclsid.exe first loads the shell extensions and does a quick check on them before it sends an 'ok' to the shell indicating that it's safe to load the extension.
See here for some details about verclsid.exe.

Related

Install a personal firefox web extension permanently

Previously, I could write an addon for personal usage packed as something.xpi and I clicked on it to install it.
After a while, mozilla introduced xpinstall.signatures.required which you could still get around it.
However, it did not stop stabbing developers who are interested to have a personal addon isolated from the world. Today, only web extensions are working and my XUL based addon is thrown away. The tutorials only talk about temporary installation of a web extension while I want my one runs on firefox forever.
Beside whether I can use web extension to write into files or create a GUI in an independent page, I have a bigger challenge:
How can I install a local web extension permanently without creating a Mozilla account for personal usage?
Navigate to the folder where your extension is located. You can build it in the usual way using web-ext:
web-ext build
You can install this ZIP file permanently in Firefox by going to about:addons and dragging this file into the tab.
In order for this to work, you need to set xpinstall.signatures.required to false in about:config (works only for Nightly and maybe Developer Edition).
Apart from setting xpinstall.signatures.required to false, you need to add this to your manifest.json:
"browser_specific_settings": {
"gecko": {
"id": "some-name#example.org"
}
}
Found on https://www.reddit.com/r/firefox/comments/blqffs/how_to_permanently_add_temporary_addon/exh2u3o/, thanks to "alexherbo2".
You need a "blueish" Firefox -- Developer Edition (effectively beta) or Nightly (unstable, updated every night).
You can get them from https://mozilla.org/firefox/channel/desktop/.
Then xpinstall.signatures.required will work again.
(As for permissions--you can create a GUI in a tab or a popup, but I don't think you can do it in a separate window (unless you do a webpage-style popup window). You won't be able to write to arbitrary files anywhere on the system--which is a good thing! You can write to the Downloads folder, and read/write some sort of internal storage, but that may not expose the actual files involved. For more information see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Working_with_files.)
What you should be looking for is having your extension signed by Mozilla as Unlisted.
See Mixing Listed and Unlisted Add-ons on addons.mozilla.org blog post for an overview.
That way, AMO does not host nor (normally) review your extension; it simply runs some basic automated checks and immediately signs your extension so that it can be privately distributed as an XPI.
For those interested in developing/running an extension from a local directory without having to package or load it manually via "Load Temporary Addon..." from about:debuggin#/runtime/this-firefox please go to this github repository.
From the README.md:
The procedure involves a few steps, but it needs to be done only once.
First you need to enable AutoConfig aka userchrome.js by copying the file config-prefs.js to [Your Firefox install directory]/defaults/pref
Note: For best security, on Windows it is best to leave your Firefox install in "c:\Program Files" so that your config-prefs.js and userChrome.js can only be modified when you are in root/admin mode.
Then you need to edit the file userChrome.js and modify the function installUnpackedExtensions() to reflect the locations of your own addons.
The modified userChrome.js then must be copied to your Firefox installation directory. For example on Windows this is usually "c:\Program Files (x86)\Mozilla Firefox" for the 32-bit version of Firefox. You can rename the file, but remember to modify the corresponding line pref("general.config.filename", "userChrome.js") in defaults/pref/config-prefs.js
Now your addons from your local directories will be loaded automaticaly whenever Firefox starts. After editing your code remember to reload it from about:debuggin. You can also get there via the menu by selecting "More Tools", then "Remote Debugging", and click on "This Firefox" on the left side (but the quickiest way is to bookmark it and then add a bookmark keyword such as "dbg" for quick access.)
Please note that this is an automated install of the extension every time Firefox starts, so it is not quite the same as a "permenent install". That is, this procedure has exactly the same effect as clicking on "Load Temporary Addon..." from the about:debuggin page, just that the process is now automated via userChrome.js. This means that if you have code that does something after the installation of the extension such as browser.runtime.onInstalled.addListener(details => { if (details.reason == "install") { ...do something after install... }); then this code will be called every time Firefox is launched.
You can try setting the preference extensions.legacy.enabled (this will only work in Nightly or Dev Edition).

Why does Windows Shell context menu handler break power-user menu (Win+x) on Windows 8/10?

My custom Windows shell context menu handler works like a charm, for all Windows versions from XP to 7, but on Windows 8, 8.1 and 10, installing it breaks the Win+X menu (sometimes called "Power user menu", or "Quick Access menu", or "WinX menu"): when hitting Win+X, the menu is displayed as expected, but its items do not work anymore (nothing happens when I click on them), except for the last four items at the bottom which still work as expected ("Search", "Run", "Shut down/Sign out", "Desktop"):
I quickly found out on Google that it was a well known issue for a great number of shell extensions that were not "compatible" with Windows 8/10. But sadly, I only found application users talking about this issue and its "solutions", and no developer talking about this. And the two "solutions" proposed by these users were:
Unregistering this shell extension
Uninstalling the app that registered this shell extension (which leads to solution 1...)
See for example this, this, or this to read people talking about this issue.
Note: my shell extension is applied for the * file type, which means all files.
Several days later, I found the cause of this issue in the shell extension source code, so I thought it would help other developers to share it on StackOverflow, as a self-answered question (I didn't find this question). See answer above.
I first looked at the shell extension sample code provided by Microsoft (which doesn't cause this issue), compared it with my code, and progressively replaced parts of my code with Microsoft's code and testing it after each replacement.
I found out that what prevents power-user menu to work is what you return in method InvokeCommand() from IContextMenu interface: if your extension cannot handle the given verb, it shall always return E_FAIL so that Windows tries with other implementations of IContextMenu (see Microsoft documentation for more details). It seems that when a power-user menu item was clicked, Windows first called my extension (* file type), then since it didn't return E_FAIL for this unknown verb, Windows thought that my shell extension has processed this event, so it didn't process it through the nominal power-user menu callback.
By the way, three things seem very weird to me:
Why does Windows even try to process this power-user menu event with a shell file extension? Is this menu coded using the same design/mechanism as any other Explorer's file contextual menu?
Why does this bug didn't produce more side-effects yet? I mean this should have broken the whole shell extension system right from the beginning, no?
Why do so many applications has this bug? (meaning why so many applications do not return E_FAIL as expected?). It's been a while now that I've written this code, I can't really remember where it comes from, but I guess it comes from a Microsoft sample or any Microsoft employee tutorial (far too Microsoft-oriented to be coded by yourself). If it's the case, that may answer the question why so many shell extensions cause this issue...
I would be interested if someone has some ideas to share about this subject!
By the way, I hope my post can help other developers. When looking at the new Microsoft example that works like a charm, I was first afraid having to rewrite all my shell extension from their sample without knowing what was wrong in my code!

Why does my DLL not seem to be called?

I have a COM DLL, coded in Delphi. It should be invoked via an Active X control when a web page loads in MS IE (via soem JavaScript on the page).
Btw, this all works fine with an existing serial port interface, but I am recoding teh DLL to read from USB; all else is unchaged.
It works fine in the Delphi IDE, but not "in the field". The active X control should request it to read some input from a USB port and should then send that to the web page.
Reading from the USB device works, as I can open Notepad and see the value being written there.
The DLL will display a form, and a dialog box, and will write to the system debug trace. Since I am seeing none of these when loading the web page in MS IE, I think we can assume that Aective X control is not calling into the DLL.
In MS IE I have enabled all Active X options.
in c:\Windows\System32 (which is equivalent to c:\Windows\SysWOW64), I have regsvr32.exe -u my_dll.dll and then regsvr32.exe my_dll.dll both of which the system announced to be successful
I searched, and there is only one copy of my_dll.dll under c:\Windows
and it has the correct size and date/time
my %path% is %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem; for system and empty for user
Any idea what I am doing wrong? Or how I can go about tracking it down?
If you are loading the ActiveX control in webpage through javascript, you will have to package the control for web deployment. See this example for how to do this in your javascript and check whether you have done properly it or not:
Calling Activex Control 's Functions from javascript
Once you do the above thing correctly and open your website in IE, the web-page will at least "load" the ActiveX control. Beyond that, you can display message-boxes or write logs in your Delphi code to track down the actual coding issues.

Properties of richtextbox control cannot be set

On one computer 'A' (win vista 32 bit) if I run my program in debug mode all the richtextbox controls throw 'property cannot be set' errors.
I can go on to build the exe (without error ) and the full application OK
But when I then install and run the application on this computer or on computer 'B' (win xp) the same problems occur on both.
However if I run the exact same code in debug mode on computer 'B' there are no errors.
If I build and install the application on computer 'B' it works fine. If I then install this application on computer 'A' it also works fine.
When putting together the application for distribution, both computers use identical copies of richtx32.ocx (it, like the code, is checked out from the same repository).
If I check out previous copies of the code on computer'A' (that used to previously behave OK) they also now exhibit the same problems as the latest version of the code.
I don't have a clue what's going on, please help!
I'm seeing multiple references to the Property cannot be set message being resolved in the version of the Rich Text Control that is distributed in Visual Studio 6.0 Service Pack 4, and another Property cannot be set message fixed in SP5.
First and foremost, make sure that a minimum of SP5 is installed; I'd just go with SP6.
For reference, my Microsoft Rich Textbox Control 6.0 (SP6) is at C:\Windows\System32\RICHTX32.OCX, and is version 6.1.97.82.
I know you said that both machines have the same copy of the control installed; for the sake of completeness, you may want to double-check that the new control was registered after installation.
EDIT:
I exported the HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402} reg key:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}]
#="Microsoft Rich Textbox Control 6.0 (SP6)"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Control]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{0DE86A52-2BAA-11CF-A229-00AA003D7352}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{0DE86A53-2BAA-11CF-A229-00AA003D7352}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{0DE86A57-2BAA-11CF-A229-00AA003D7352}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{40FC6ED4-2438-11CF-A3DB-080036F12502}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{40FC6ED5-2438-11CF-A3DB-080036F12502}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\InprocServer32]
#="C:\\Windows\\system32\\RICHTX32.OCX"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\MiscStatus]
#="0"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\MiscStatus\1]
#="131473"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\ProgID]
#="RICHTEXT.RichtextCtrl.1"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Programmable]
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\ToolboxBitmap32]
#="C:\\Windows\\system32\\RICHTX32.OCX, 1"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\TypeLib]
#="{3B7C8863-D78F-101B-B9B5-04021C009402}"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\Version]
#="1.2"
[HKEY_CLASSES_ROOT\CLSID\{3B7C8860-D78F-101B-B9B5-04021C009402}\VersionIndependentProgID]
#="RICHTEXT.RichtextCtrl"
A bad richtx32.oca file in the system32 directory seems to have been the cause of this.
Here's what an .oca file does:
Some of the properties of the control are provided by the framework
and some by the control itself. Programmatically, the properties from
the framework and the control all appear as properties of the control.
In order for these properties to appear, Visual Basic creates an
extended type library when the control is loaded into the toolbox.
Because the process of reading the control's type library and creating
the extended type library is time consuming, Visual Basic caches the
extended type library information into an OCA file.
If you delete the OCA file for a control Visual Basic recognized,
Visual Basic will recreate the .OCA file when you load a project
requiring the control. This recreation process comes with a time
penalty.
So it seems that having a bad .oca file in existence can mean that the properties of the control both in the IDE and in the compiled .exe will be affected.
The solution is to delete the .oca file in the system32 folder and then load the project again.

Windows 7: Property Handler works in Explorer but Not FileOpenDialog?

Working on writing a custom property Handler for our custom file type in windows 7. I have installed the Windows 7 SDK and built the sample Property Handler. After registering the handler, it works great in Windows Explorer, but in the common file open dialog the custom values do not appear. Does anyone know if there is something special I need to do to get the properties to appear in common dialogs?
Explorer:
File Open Dialog:
OK, figured it out. Here is the deal. My app is 32 bit and I am on a x64 system. Because the PropertyHandler is written in x64 to support the shell out of process. But for the file open dialog it needs to run inprocess, so the x64 dll can not run. I confirmed this by creating a quick x64 app and the fileopen dialog works the same as the OS. Hope this helps someone else in my shoes later on, hate answering my own question, but don't want people wasting NRG on this one as I found the solution.

Resources