What is the difference between Shell and ShellEx in Windows Registry? - windows

I'm trying to add a custom context menu in windows registry, I found a shell key and shellex key that seems to both work the same thing? Why is there 2 and what are they for?

The Shell key is for static verbs used by ShellExecute and file-type context menus. They are simple to implement because they are just a string that specifies the command. They can be extended with optional COM objects (DropTarget etc.) if required.
The ShellEx key is for shell extensions, these are COM objects and there are various extension points in the shell and each type is a subkey of ShellEx. ShellEx\ContextMenuHandlers is the shell extension version of the plain Shell key. The different types of shell extensions are listed here.

Related

Trying to 'emulate' a document folder

I am a 3rd party, and I would like to start an 1st party application and virtualize somehow a document folder that I would decide the location.
The first application would not touch the real 'my document' folder but instead save the file in a location I would set.
I don't want to change the registry entries for the personal folders, I want it just for this application.
I did some research but didn't find anything like that. Is that possible without a virtual machine? I would try to work in VB6, I want to test something on xp and win7. It's about a game redesign, and I would like the person to be able to have my program, and the original game installed on the PC without the configuration folders in 'my document' colliding.
I should mention that I cannot pass parameters to it because I am launching the 1st party application through a 2nd party executable already.
Thank you!
Yanick
Of course you can, with a text file (or a program). MS made it easy.
Here is someone quoting my post, who is quoting Raymond Chen directly,
http://www.pcreview.co.uk/threads/re-create-system-folder.522854/
Creating Shell Extensions with Shell Instance Objects
Raymond Chen
Microsoft Corporation
February 2000
Summary: A traditional shell namespace extension requires the implementation
of a COM in-process server. Shell instance objects allow you to create
simple shell extensions without having to write a single line of code. This
article describes how shell instance objects and shell command objects can
be used to easily deploy simple shell extensions. (5 printed pages)
Contents
What Is a Shell Namespace Extension?
What Is a Shell Instance Object?
Shell Objects That Can Be Created as Shell Instance Objects
How About an Example?
Shell Command Objects
Conclusion
What Is a Shell Namespace Extension?
Shell namespace extensions allow you to create "virtual folders" in the
shell. For example, the Recycle Bin icon on the desktop is not an actual
file system directory, but rather represents a collection of items that is
maintained by the Recycle Bin shell extension.
Details on creating shell namespace extensions can be found in the Platform
SDK section of the MSDN Online Library
(http://msdn.microsoft.com/library/psdk/shellcc/shell/shell_adv/namespace.ht
m).
Writing a shell namespace extension can be quite an ordeal. Fortunately, the
shell provides an easy way to create certain types of simple shell namespace
extensions, as this article will show.
What Is a Shell Instance Object?
A shell instance object is a special kind of shell extension provided by the
shdocvw.dll component. Whereas a traditional shell extension requires a DLL
to implement the object, a shell instance object retrieves everything it
needs to know from the registry.
How the shell creates a shell instance object
1.. The shdocvw.dll component is loaded by virtue of being registered as
the InProcServer32 for the shell instance object.
2.. When shdocvw.dll is asked to create an object it does not otherwise
recognize, it checks the registry key for a subkey named Instance. If found,
it reads the CLSID value of that subkey and passes that CLSID to the
CoCreateInstance function. (For lack of a better term, let's call this the
"host" object.)
3.. Next, shdocvw.dll looks for a subkey of Instance named InitPropertyBag
or InitStream. If found, it then creates an IPropertyBag or IStream
(accordingly) based on the contents of the registry key and passes it to the
IPersistPropertyBag::Load or IPersistStream::Load method (accordingly).
4.. Finally, shdocvw.dll returns the now-initialized host object as the
shell instance object.
Shell Objects That Can Be Created as Shell Instance Objects
There are two shell objects that support being the host object of a shell
instance object, namely the Shell link object and the Shell folder shortcut
object.
Both of these objects support the IPersistPropertyBag interface, so you can
use the InitPropertyBag method of initializing them. (It so happens that
both objects also support IPersistStream, but initializing a shortcut from a
registry stream is much more cumbersome.)
The property bag you provide in the registry describes the target of the
shell link or shell folder shortcut object. There are three supported forms
for this property bag.
Targeting a shell special folder
InitPropertyBag
TargetSpecialFolder=REG_SZ:"<special folder number>"
Notice that this is a REG_SZ registry value even though it represents an
integer. Both decimal and hex notation are supported.
Targeting a directory inside a shell special folder
InitPropertyBag
TargetSpecialFolder=REG_SZ:"<special folder number>"
Target=REG_SZ:"<subdirectory name>"
The subdirectory name can contain embedded backslashes.
Targeting a directory by explicit path
InitPropertyBag
Target=REG_SZ:"<full path to target directory>"
How About an Example?
Here's a copy of the registration that creates the Fonts folder icon in
Control Panel:
HKEY_CLASSES_ROOT
CLSID
{D20EA4E1-3957-11D2-A40B-0C5020524152}=REG_SZ:"Fonts"
InfoTip=REG_SZ:"Displays and manages fonts on your computer"
DefaultIcon=REG_EXPAND_SZ:"%SystemRoot%\system32\main.cpl,9"
InProcServer32=REG_EXPAND_SZ:"%SystemRoot%\system32\shdocvw.dll"
ThreadingModel=REG_SZ:"Apartment"
ShellFolder
Attributes=REG_DWORD:0x60000000
WantsFORPARSING=REG_SZ:""
Instance
CLSID=REG_SZ:"{0AFACED1-E828-11D1-9187-B532F1E9575D}"
InitPropertyBag
TargetSpecialFolder=REG_SZ:"0x0024"
Target=REG_SZ:"Fonts"
Because {D20EA4E1-3957-11D2-A40B-0C5020524152} is registered in the Control
Panel namespace, a Fonts folder shortcut is installed in Control Panel.
Let's go through this registry key step by step.
a.. The GUID {D20EA4E1-3957-11D2-A40B-0C5020524152} was generated by
running the uuidgen program found in the Platform SDK. Of course, when you
create your own instance objects, you should run uuidgen and use your own
GUID. The name of the icon as it appears in the namespace is also provided
here.
b.. The optional InfoTip string is displayed when the user hovers over the
icon.
c.. The DefaultIcon string provides the name and icon index for the icon
to display for this item.
d.. The InProcServer32 key must be set to the shdocvw.dll file, and the
threading model must be set to Apartment.
e.. The ShellFolder key sets the Attributes to a collection of SFGAO_
values, which we wish to apply to the folder shortcut. The SFGAO_FOLDER flag
must always be set. Because the target is a file system folder, the
SFGAO_FILESYSTEM flag is also set in the Attributes, and the WantsFORPARSING
value is set to an empty string. (If the target is not a file system folder,
the WantsFORPARSING value should not be created.)
f.. The Instance key sets the CLSID value to the string representation of
CLSID_FolderShortcut. This indicates that the object instance should create
a folder shortcut.
g.. The InitPropertyBag key indicates that the folder shortcut will be
initialized with the IPersistPropertyBag interface. The two values inside
the property bag specify that the target is the subdirectory "Fonts" in the
special folder 0x0024, which is CSIDL_WINDOWS.
Shell Command Objects
Another type of shell extension object is an icon that when double-clicked
runs a command. This, too, can be created without having to write a COM
server. For example, here is a command object that is used by the My Network
Places folder:
HKEY_CLASSES_ROOT
CLSID
{D4480A50-BA28-11d1-8E75-00C04FA31A86}=REG_SZ:"Add Network Place"
InfoTip=REG_SZ:"Connects to shared folders, Web folders, and FTP
sites."
DefaultIcon=REG_EXPAND_SZ:"%SystemRoot%\System32\netplwiz.dll,-107"
ShellFolder
Attributes=REG_DWORD:0x00000000
Shell
Open
Command=REG_EXPAND_SZ:"rundll32 ..."
Most of this registry key should look familiar, so I will only highlight the
differences from shell instance objects:
a.. There is no InProcServer32 key.
b.. The Attributes of the ShellFolder key should omit the SFGAO_FOLDER
flag because this item is not a folder.
c.. Instead of an Instance key, we have a Shell key, which has the same
structure as a progid key. The "Open" verb is the default action for
double-clicking. You can also create other verbs, which will appear on the
context menu. For example, the Internet Explorer icon creates a custom verb
called "Open Home Page."
Details on the structure of the Shell key can be found in the Platform SDK
section of the MSDN Online Library under the topic heading "Extending
Context Menus"
(http://msdn.microsoft.com/library/psdk/shellcc/shell/shell_basics/context.h
tm).
Conclusion
Shell instance objects and shell command objects allow you to deploy simple
shell extensions with a minimum amount of work. For example, you might
create a command object in the Control Panel folder called "Troubleshoot,"
which runs a troubleshoot program. Or you might create a shell instance
object that hosts a folder shortcut to a collection of system administrative
tools on a shared network server. Shell instance objects and shell command
objects allow you to easily deploy these types of shell extensions.
My solution was to search the executable with a hex editor and manually edit it to another folder. Of course I had to choose a folder with less or equal number or character in the path.
Thank you all.

QTP AOM Model Intellience Not Working

I want to use QTP AOM(Automation Object Model) using vbscript. I use VbsEdit to develop this script but I did not get any intellience from this editor even I also try this from excel developer window. There also intellence assistance is not available.
I need this because if it is not appear then how can I know the available(open) methods and properties from this COM object.
I have also another question that we write this below line to instantiate a QTP object using vbs
CreateObject("QuickTest.Application")
For excel
CreateObject("Excel.Application")
How can I know the COM objects name means can I list down all COM object name programmatically.
There are two questions here.
Why don't you get intelisense for the QTP object in the IDE you're using (VBSEdit)
Intelisense is a feature of the IDE, you should tag this question VBSEdit, not QTP
Where can I get a list of all the COM objects in the system?
When you use CreateObject you're specifying a ProgID which is a string identifyier for a COM class (slightly more human readable than a CLSID. COM uses the registry to maintain its Prog and Cls IDs, you can find the ProgId's under the HKEY_CLASSES_ROOT registry hive (look for keys with a child CLSID key).

Add explorer context menu item for PDF files from delphi

I have my application written in Delphi XE that works with PDF files. Applicaiton is Win32. On start I would like to ensure that there is my item in explorer context menu for PDF files. I would like to be able to specify whether it should be added for active user only or for all users (with UAC I will need to restart with Admin privileges but thats ok).
I started with How to associate a Delphi program with a file type, but only for the current user? and How to add item to windows explorer content menu in delphi? . I tested it with manual registry editing via regedit and it worked fine for "new" extensions. But for .pdf it is more complicated as it will be most probably already present in the registry.
On my PC the .pdf key is referencing AcroExch.Document . But adding shell/something subkey to the AcroExch.Document key is not working because it has CurVer subkey referencing to AcroExch.Document.7. However another PC with another verison of Acrobat had this names a little different. It is no problem for me to follow the CurVer reference but is that a correct approach? And what about situation where no PDF reader is installed, how should I name my keys so Acrobat won't overwrite them when installed?
But more pressing matter is in which root should I put my keys? How to associate a Delphi program with a file type, but only for the current user? is mentioning HKLM (Local Machine) and HKCU (Current user). Its seems rather straightforward but I am unable to set values in HKLM from Delphi. Strangely I can create keys:
var reg:TRegistry;
key := '\Software\Classes\'+keyname+'\shell\'+name+'\command';
reg.CreateKey(key);
but I am getting Access Denied when trying to write the actual value:
reg.OpenKey(key,false);
reg.WriteString('',command);
I am getting the same Access Denied exception even on WinXP, no matter if the applicaiton is running as Admin (Win7), I even tried to set permissions (Everyone full control) for the key via regedit (I can edit the value via regedit without problems). I tried creating the registry with different access modes, all with no luck:
reg := TRegistry.Create(KEY_WRITE or KEY_WOW64_64KEY);
reg := TRegistry.Create(KEY_ALL_ACCESS or KEY_WOW64_64KEY);
reg.Access := KEY_ALL_ACCESS;
reg.Access := KEY_WRITE or KEY_WOW64_64KEY;
reg.Access := KEY_ALL_ACCESS or KEY_WOW64_64KEY;
With HKCU everything works fine.
So I tried writing into HKEY_CLASSES_ROOT and it works and actually puts the keys exactly where I want (into HKLM) if running as Admin. But according to http://msdn.microsoft.com/en-us/library/windows/desktop/ms724475.aspx
The HKEY_CLASSES_ROOT (HKCR) key contains file name extension associations and COM class registration information such as ProgIDs, CLSIDs, and IIDs. It is primarily intended for compatibility with the registry in 16-bit Windows.
I do not like the note about the primary purpose being compatibile with 16-bit Windows. And the actual conditions where the changes will be written is more complicated than I would like.
So basically I have these questions:
What is the advantage of using AcroExch.Document and CurVer instead of pointing directly to AcroExch.Document.7? And what are the "best manners" when adding my keys into this structure? What about the case when the .pdf is not yet associated with anything?
Where should I put my keys and why I am not able to write into HKLM?
Edit:
The problem with Access Denied when writing to HKLM was caused by my error. I did use in previous code openKeyReadOnly and I did not notice that it will swtich the Access property to readonly for all subsequent calls.
To answer your other question, if Adobe is not installed yet then obviously the PDF keys will likely not exist in the Registry yet so you would have to create your own .pdf and ProgID keys so that you can attach your Shell command on it. If Adobe is installed afterwards, it is likely going to wipe out your keys and replace them with its own, so you would have to recreate your Shell command within Adobe's key structure. Your app can query the Registry to check for that condition periodically, such as at startup.
You have asked two separate questions. Since I know the answer to one and not the other, I'm going to answer just one. For future reference, I do recommend that you ask a single question at a time.
Where should I put my keys?
You are correct in discerning that you should not use HKCR. The documentation for HKCR says:
Class registration and file name extension information is stored under
both the HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER keys. The
HKEY_LOCAL_MACHINE\Software\Classes key contains default settings that
can apply to all users on the local computer. The
HKEY_CURRENT_USER\Software\Classes key contains settings that apply
only to the interactive user. The HKEY_CLASSES_ROOT key provides a
view of the registry that merges the information from these two
sources. HKEY_CLASSES_ROOT also provides this merged view for
applications designed for previous versions of Windows.
....
If you write keys to a key under HKEY_CLASSES_ROOT, the system stores
the information under HKEY_LOCAL_MACHINE\Software\Classes. If you
write values to a key under HKEY_CLASSES_ROOT, and the key already
exists under HKEY_CURRENT_USER\Software\Classes, the system will store
the information there instead of under
HKEY_LOCAL_MACHINE\Software\Classes.
So, it is reasonable to use HKCR for reading, but for writing you typically need to exert control over whether to write to HKLM or HKCU. And that means that you cannot write to HKCR.
So, write to HKLM\Software\Classes for machine-wide settings, and HKCU\Software\Classes for user-specific settings.
Note that in Windows 7 and later neither of these keys is redirected and so you do not need to worry about using KEY_WOW64_64KEY. However, in Vista and XP64, and the equivalent server editions, these keys are redirected and reflected. Which means that it might be prudent to use KEY_WOW64_64KEY.

Need to write a shell extension

I need to write a shell extension for a small context menu.
unfortunately i reused the code available in open source which uses .net 4.0
now the problem is the requirement is I shud not use .NET 4.0.
Instead is there a way where in I can make an entry in the registry so that the shell extension pops out
My requirement is ....
1. The shell extension context menu should display only on .txt, .csv, .xls files.
2. Upon click of shell extension I need to start a different process, by passing the full name of the file on which we click as parameter to the process.
If you just want to add items to the context menu for certain file types, and in response launch an external application, you don't need to write a shell extension. Registry entries are enough to express this.
As the http://www.jfitz.com/tips/rclick_custom.html article you linked to says, for each file type you want to act on, you need to add a new registry key under the Shell subkey, then create a subkey called command, whose value is the name of the application to launch.
To pass the name of the file you clicked on to this external application, add "%1" to the command. Include the quotes, so that if the file's name contains spaces, it will still be treated as one token by the receiving program.

Read HKU VB and VBA Program settings

How do I read a particular vb program settings or registry entry from the registry of the key "HKEY_USERS\S-1-5-21-1390067357-1965331169-725345543-1003\Software\VB and VBA Program Settings".A standardized way to read as the part after hikey_users and before software changes with the pc used,but the vb programs do write perfectly at the right place.Is there some variable that defines the registry key location ?
VB6 has built-in functions for manipulating the registry, like GetSetting. These functions use registry keys underneath HKEY_CURRENT_USER\Software\VB and VBA Program Settings
HKEY_USERS\S-1-5-21-1390067357-1965331169-725345543-1003\Software\VB and VBA Program Settings is just another path to the same set of keys: the long string in the middle identifies the current user by their ID, rather than just saying "the current user".
So the answer is:
If you are using VB6, just use GetSetting.
If you are using VBScript, use WshShell.RegRead and work on HKEY_CURRENT_USER\Software\VB and VBA Program Settings. Example code in this article.

Resources