I am writing a Shell Namespace Extension.
How may I force explorer to access (and open) items that are not enumerated with IShellFolder::EnumObjects by typing their parsing name in the address bar?
I have seen SFGAO_NONENUMERATED flag which I believe is used to mark such items (so in theory it should be possible, otherwise why do one need this flag?). I don't want to use SFGAO_HIDDEN or SFGAO_SYSTEM because such items could be seen nevertheless.
I am expecting explorer to call IShellFolder::ParseDisplayName with absolute or at least relative path to the item requested. But instead it is calling IShellFolder::ParseDisplayName only for the first segment of the parsing name (basically the first folder's parsing name). After this explorer queries content of each sub folder via IShellFolder::EnumObjects and calls IShellFolder::GetDisplayNameOf to get both display and parsing name of each item enumerated.
Based on this comment from Raymond Chen I understood that it is normal for explorer to rely on both display and parsing names to retrieve the item requested in the address bar. But the biggest issue here is that my items (that I want to obtain) are not enumerated. So explorer does not know about their existence.
Related
How does one find the exact verbs to be used with the Windows API function FolderItem.InvokeVerb? The documentation says, "It must be one of the values returned by the item's FolderItemVerb.Name property." However, this does not seem to be true.
Using a folder as an example, if you run this on Windows 10 (using PowerShell):
$Shell = New-Object -ComObject 'Shell.Application'
$Shell.NameSpace('C:\Windows').Self.Verbs()
you will get a list that looks like this:
Application Parent Name
----------- ------ ----
&Open
Pin to Quick access
Scan with Microsoft Defender...
... and so on.
Those Names are what you get in an Explorer context menu, but they do not work with InvokeVerb. For some of them, such as &Open, all you have to do is remove the &. For others, such as Pin to Quick access, the actual verb that works is altogether different (pintohome). How can one reliably find these "actual" verbs for an arbitrary item?
I have found that the verbs that do work with InvokeVerb correspond to the sub-keys that you can find in the Registry under HKCR\<class name>\shell. However, even knowing that does not make things simple. I have found some verbs before by searching HKCR for the string returned by FolderItemVerb.Name, but that doesn't work if the string is localized. If you happen to know the name of the class, you could look there directly. (Using the folder example, pintohome is one of the keys under HKCR\Folder\shell.) However, when it is localized, there is nothing there that directly indicates this is the verb you are looking for, so you have to try it to find out. And, if you are inside some special shell folder or namespace extension, you might not know what class name(s) to even go looking for.
Referring my question to this answer: https://stackoverflow.com/a/4016075/698266, in particular step 3 says "Otherwise, if the application has used an Open or Save As dialog box in the past, the path most recently used is selected as the initial directory."
Where does Windows save this information?
Note: by experimenting, it seems to be linked to the application file name without its path - i.e. the same executable copied in different directories "sees" the same last path information, while changing the exe file name makes the dialogs point to the user's Documents directory.
My actual interest is for testing purposes. I need to "reset" this information in order to test my application in conditions similar to a first run.
Windows XP uses HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedMRU and the format of each item seems to be ExeFilename+Path with both strings zero terminated and in UTF-16LE format. The MRU list is stored as a string named MRUList.
Newer versions of Windows uses HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRU and HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRULegacy and the format seems to be ExeFilename+ItemIdList (ExeFilename in UTF-16LE and zero terminated). The MRU list seems to be a list of DWORDs in a binary value named MRUListEx and the list is terminated by 0xffffffff.
I would assume that the change happened in Vista because that is when the new IFileDialog was added. LastVisitedPidlMRULegacy is probably used when GetOpen/SaveFileName is called with a custom template and/or hook function.
I finally found the answer myself.
For Windows 10 (this may be different in different versions of Windows, as David pointed up) there's a list of values in the registry that keep track of the executable name and its associated last "visited" path.
The list can be found in this key:
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRU
In order to reset the default open/save path for a particular program, you have to find the value whose data string (UNICODE) starts with your executable name and delete it. If you watch at the data string, you'll notice that the last used path is there, after the executable name.
If you look at Classic Shell Start menu, you see that it has a section for recent applications. Every item in the section can contain popup menu, usually used for displaying recent documents, opened earlier in the application. For instance, the 'Word' item contains all .doc and .docx files recently opened in Word. I know a way to build such list: get all links from the 'Recent' folder and filter out matched documents, by .exe name.
But Classic Shell Start menu also shows popup menu for programs like RDC. For RDC client, namely, it shows a list of recent connections. It seems there is a concept of pseudo-documents in Windows, but I have never heard of it. How to get such list for a random .exe file?
Regards,
The shell maintains the list of recent documents. SHAddToRecentDocs allows a program to add an item to the list. The item can be:
A path and filename
A PIDL representing the shell object
(Windows 7+) A SHARDAPPIDINFO or SHARDAPPIDINFOIDLIST structure that identifies a shell item, and associated application.
(Windows 7+) An IShellLink
The key idea from the list and documentation is that the item can be a PIDL, which can represent a fancy kind of 'file'. (What you called a pseudo-document. This is an oversimplification. Read the documentation.)
To obtain the recent files list, use SHGetFolderLocation specifying CSIDL_RECENT and use the returned PIDLIST_ABSOLUTE to iterate the shell items.
If the item is not a file the list can be retrieved through the COM IApplicationDocumentLists which requires an Application User Model ID. This excludes pinned items, for which there is no programmatic access for the same reason that there is no access to the start menu pin list.
There are a lot of caveats to this, which is best explained by the documentation:
SHAddToRecentDocs
Managing the File System
(edited to add information about the jump list, and missing IShellLink from the list.)
NSE meaning namesapce extension
(https://msdn.microsoft.com/en-us/library/windows/desktop/cc144095%28v=vs.85%29.aspx)
I have a namespace extension developed using the DefView.
I am handling FMTID_PropList+PID_PropList_ContentViewModeForBrowse and returning the correct proplist-string.
When I browse my nse in "Content View" in Windows Explorer, renaming does not work.
Additionally, I notice that Windows Explorer prefixes the value of my first column (which is the item name) with "Name:
- it does not do this for items in the filesystem.
How can I solve both the above issues?
I copied the question from:
https://social.msdn.microsoft.com/Forums/en-US/a88ca56d-542e-46a8-81b4-7c37431ea26a/renaming-in-my-nse-does-not-work-in-content-view?forum=windowsuidevelopment
I'm having the exact same issue and could not find any help on the web.
You are using obsolete format of proplist string. It was actual in Windows XP era. Starting from Windows Vista it is necessary to use new format. Instead of GUID and PID you must use canonical name of property key. That why Windows does not allow user to rename your object in content view mode.
{b725f130-47ef-101a-a5f1-02608c9eebac} 10 is equal to PKEY_ItemNameDisplay with canonical name System.ItemNameDisplay.
"~" char before canonical name has a special meaning. If it does not present shell shows label before value. In case of System.ItemNameDisplay label is "Name".
Is there any way to find quickly the program behind a rexx/clist panel.
I know that i have check one by one all the panle librairies to find the panel.
But it takes lot of time.
Thanks
First step is is to turn panelid on with the ispf panelid command
panelid on
This will list name of panel on all ISPF panels being displayed
Actually you do not need to search each panel library, you can use Ispf rexx program
to allocate a DataId to ispplib and edit using the DataId i.e.
/* rexx */
address ispexec
'LMINIT DATAID(didVar) DDNAME(ISPPLIB)'
'edit DATAID('didVar') memeber(panelname)'
'lmfree DATAID('didVar')'
Note: If you make changes while editing, the changes are saved in the first library in the list. So if ISPPLIB is setup as
my.panels
test.panels
prod.panels
any changes will always be save in my.panels
Note: if you edit without a specifying the member, the member list will include a dataset number relating to the top level where the panel will be picked up from.
Note: There is almost certainly a limit on the number datasets that can be accessed this way. So if there are a lot of datasets allocated to ISPPLIB, there could be issues.
Hopefully there will be a
Relationship between where the panel is stored and where the rexx/clist is stored
relationship between the panel name and the rexx/clist name; often they are nearly the same. Some times the panel might have a P at a certain character position while the rexx might have a R
If there is no relationship between the panel and the Rexx/clist; you will have to search for it. You could set up a batch search for to search for the panel in all the rexx/clist libraries. A bit of a pain to set up, but it only has to be done once and then you have it for future use.
If you want to get really smart you could use the LM services to extract rexx/clist libraries
Building on some of what #Bruce Martin said, type TSO ISRDDN on any COMMAND ==> line in ISPF. Use the member command to search your SYSPROC and SYSEXEC concatenations. You can also use SRCHFOR when in a member list, looking for the panel name.