How to register a System Supplied Property Handler for XPS and OPC files in registry for a custom file type? - windows-shell

I'm creating a custom file format for use by my application based on the OPC (or maybe the XPS) file format. This MSDN link, Using System-Supplied Property Handlers, gives an example but it doesn't appear to be correct. Does anybody know how to do this properly?
Edit:
This can apply to OPC files as well as XPS. XPS is build on top of OPC.

You have to:
Create a key named with your extension (e.g. a key named .doc) under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers.
Then set the default value for the key you just created to {45670FA8-ED97-4F44-BC93-305082590BFB}
Under Root/SystemFileAssociations add a key named with your file extension (e.g. .doc).
Under that key add "shellex\PropertyHandler"
Set default value under the PropertyHandler key to {45670FA8-ED97-4F44-BC93-305082590BFB}.
Now you have to tell Windows what properties to display depending on circumstance.
Add FullDetails, PreviewDetails, ExtendedTileInfo, and InfoTip keys to the Root/SystemFileAssociations/ key.
This property handler is good for both OPC (open package conventions) and XPS files.
PreviewDetails is the property pane at the bottom of windows explorer (Win 7) or the left hand side of explorer (Win 8).
FullDetails is the properties you see when you right click and select properties and go to the Details tab.
InfoTip is the properties you see when you hover over a file.
ExtendedTileInfo I'm not sure about. I think it's the properties you see when you select the content folder view in explorer.
{45670FA8-ED97-4F44-BC93-305082590BFB} is the GUID for the OPC/XPS property handler given in the MSDN link in my question.
OPC is basically a standard for creating a (zipped) file type. Can see more here: MSDN Magazine - Aug. 2007 OPC - A New Standard For Packaging Your Data.
I only tested in Windows 7 but it should work in Vista and above. I'll post back after I do further testing.

Related

managing right click context menus in window 10/11: Complete control over windows context menus

Question
when you right-click on the desktop (or folder, file, etc) the context menu entries that appear are either statically generated or dynamically generated via a loaded DLL that implements specific interfaces. read more about the differences between static entries and dynamic ones here.
I just bought a new computer and decided to fully customize my windows context menu.
Basically, this question asks about complete control over your windows context menus, even the dynamic ones, and even the built-in ones(if possible).
The static entries are easy to manage and can be easily managed via the registry or a tool.
the dynamically generated entries are the problem because it's hard to understand which of the loaded DLLs caused a certain entry label to apear.
For example: context menu on certain file types(like .txt) will load an entry "Move to OneDrive". how do I find the DLL that loaded that sentence?
so to summer up, how do i:
get from the context menu entry label(eg 'Move to OneDrive') the path of the ContextMenuHandlers DLL that loaded it. Alternatively, finding out the ContextMenuHandler that generated this entry.
✅ disable its loading. (can be done by editing the UID to something else,for example prefixing with '-')
some values are restored after reboot, how do I cancel that?
('Move to OneDrive' is a true and annoying example but I asking about any entry, even the 'Rename' or 'Properties')
Possible directions:
Using Sysinternals process explorer we can search a handle or a loaded DLL, however, how can you tell in a DLL generated a specific string(eg 'Move to OneDrive')?
Example:
for documentation purposes, not actual part of the question
Following this example we can understand,
The registry entries that are responsible for the dynamic entries on the directory context menu are listed in Computer\HKEY_CLASSES_ROOT\Directory\shellex\ContextMenuHandlers
let's take the EPP Key for example:
we can see that the value of the EPP key is {09A47860-11B0-4DA5-AFA5-26D86198A780}
following this example:
HKEY_CLASSES_ROOT
   .myp
      (Default) = MyProgram.1
   CLSID
      {00000000-1111-2222-3333-444444444444}
         InProcServer32
            (Default) = C:\MyDir\MyCommand.dll
            ThreadingModel = Apartment
      {11111111-2222-3333-4444-555555555555}
         InProcServer32
            (Default) = C:\MyDir\MyPropSheet.dll
            ThreadingModel = Apartment
   MyProgram.1
      (Default) = MyProgram Application
      Shellex
         ContextMenuHandler
            MyCommand
               (Default) = {00000000-1111-2222-3333-444444444444}
         PropertySheetHandlers
            MyPropSheet
               (Default) = {11111111-2222-3333-4444-555555555555}
using our value for the EPP entry {09A47860-11B0-4DA5-AFA5-26D86198A780}, we can understand that the DLL that loaded this entry is listed here Computer\HKEY_CLASSES_ROOT\CLSID\{09A47860-11B0-4DA5-AFA5-26D86198A780}\InprocServer32, and in this case the value of this entry is C:\Program Files\Windows Defender\shellext.dll
We can 'Windows Defender' in the path, so we can assume it's responsible for loading the context entry with the label 'Scan with windows defender'
However, seems that that story does not end here, after disabling all static and dynamic entries for context directory there are still entries in the context menu. how do I revel which DLL loaded them?

settingcontent-ms file tag meaning

Windows 8 has a feature: it can launch an application from the search panel (on the right side of the screen). It works like following:
Developer registers his or her application following this instruction. It is a bit legacy instruction, but the project I participate in uses this way to register its settings.
At user logon Windows creates (if none exists) a special .xml file in C:\User\<UserName>\AppData\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\en-US with content shown below. This file has extension settingscontent-ms
As soon as user clicked on this file, the system launches the specified application (actually explorer calls for it, as I discovered by ProcMon).
Xml file content:
<?xml version="1.0" encoding="UTF-8"?>
<PCSettings>
<SearchableContent xmlns="http://schemas.microsoft.com/Search/2013/SettingContent">
<ApplicationInformation>
<AppID>windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel</AppID>
<DeepLink>%Canonical name or application path%</DeepLink>
<Icon>%App path%,-%Resource number%</Icon>
</ApplicationInformation>
<SettingIdentity>
<PageID>%GUID as in instruction above%</PageID>
<HostID>{7E0522FC-1AC4-41CA-AFD0-3610417A9C41}</HostID>
<Condition>shcond://v1#RegkeyExists;0;Regkey;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\%GUID as in instruction above%</Condition>
</SettingIdentity>
<SettingInformation>
<Name>#%App path%,-%Resource number%</Name>
<Description>#%App path%,-%Resource number%</Description>
<HighKeywords>%App decription%</HighKeywords>
</SettingInformation>
</SearchableContent>
</PCSettings>
We can see node with the name HostID. Windows writes specified in code GUID to this node, but it breaks the ability of my application to work. If I try to execute my app through this "shortcut" by clicking on xml file or chosing my app in search panel, the system shows me a message: "Unspecified error".
When I manually change the HostID value to {12B1697E-D3A0-4DBC-B568-CCF64A3F934D}, it starts to wrk fine.
I looked through registry in order to find something about these two GUIDs, but I didn't find anything. Also I looked for the difference between registry values corresponding to my app and to another, but working, app and didn't find any significand differences too.
Also I tried to delete this file and login into the system under ProcMon, I caught some moments: explorer tries to open the file and fails with ERROR_FILE_NOT_FOUND, explorer creates missing file, reads registry and writes something to created file, then it closes the file. But I didn't find anything interesting in between of these messages, that can help me to solve my problem.
I found out that registry key HKEY_CLASSES_ROOT\CLSID\%App GUID%\System.ApplicationName contains exactly the same with DeepLink tag (it was the first error in my app - specified key was empty), but the proble with "wrong" HostID remains.
Does anyone know, what it is and how to make Windows to write the rigth GUID to this tag, or at least some useful info about this tag? I just can't imagine anything else to change, but I think, that I need to change something in corresponding to my app registry keys.
I found the solution: just put app's GUID (the same as in PageID) into DeepLink.
To do this, you need to write this GUID as string value to HKEY_CLASSES_ROOT\CLSID\%App GUID%\System.ApplicationName.
That's the solution. However, I haven't found the meaning of HostID tag :(

ResourceManager returning null for default culture

I'm working on a Xamarin Forms app, using a .NET Standard library. I've used the TranslateExtension as mentioned in the docs. I've added three resource files:
AppResources.resx (with matching code-behind file, auto-generated)
AppResources.nl.resx (Dutch translations)
AppResources.fr.resx (English tranlations)
When debugging the (UWP) app, I can't get the default culture (English) to be displayed. The following line returns null:
ResMgr.Value.GetString(Text, ci);
I've add some lines for debugging, and the other two languages do return the translated value:
ResMgr.Value.GetString(Text, new CultureInfo("nl")); // OK
ResMgr.Value.GetString(Text, new CultureInfo("fr")); // OK
ResMgr.Value.GetString(Text, new CultureInfo("en")); // returns null
What could possibly be the cause of this?
Things I've tried:
I've copy-pasted the key across all resource files, so I've ruled out misspelling the resource key.
I've tested "en-GB", "en-US", CultureInfo.InvariantCulture.
I've changed the default lanuage in the appxmanifest from en-US to en.
On UWP, watch that your resource name does not have a period in it..
You also likely need to tell the UWP project what its default language is. This can be done in the .csproj in the top <PropertyGroup> element (the one with no conditions) by adding <DefaultLanguage>en-US</DefaultLanguage> (using the proper culture for your scenario).
Don't forget to set the [assembly: NeutralResourcesLanguage("en-US")] as well for the assembly containing the resources - this is required for .NET Standard 2.0 and likely PCL.
Well it seems like you've got resx files for "nl" and "fr" (which you've said works fine) but you don't have one for "en". If you're trying to get the English value like that, I would think you need an "en" file the same way you do for "nl" and "fr"
I noticed that you told about NET Standard library
ResourceManager.GetString started giving null for new entries after moving from PCL to .NET Standard
I also observed that the file AppResources.Designer.cs disapeared from the Solution Explorer (but I don't know how, was still considered) and, in the VS res editon of AppResources.resx, Access Modifier was No Code Generation.
Here is what I did to fix that:
I double-clicked on AppResources.resx and set Access Modifier to Internal or Public
In .NET Standard you may no longer be able to see "View Code" from resx files; so, I righ-clicked on AppResources.resx-> Open With -> Source Code Editor and copy the new created entries to all the others *.fr (also *.nl in your case) ...
NOTE
In the context menu you should see Run Custom Tool. You may need to delete the old AppResources.Designer.cs and do "Run Custom Tool"
Don't forget to clear the solution (or olny UWP and the standard library), close VS, delete all .\bin and .\obj and restart VS. This to ensure your issue is fixed or not using the very very new generated true code :)

how to add ocx files in vb4.0 (I am migrating from vb4 to vb6

I am migrating vb4 application to vb6.0 app. I am using windows xp. I want to add ocx controls to the application. Any simple steps to do add ocx controls/files to the application. What are .frm files
Object = "{bla-lablabla-lablabla}#2.0#0"; "THREED20.OCX"
Object = "{blabla-bla-bla-blabla-blablabla}#2.0#0"; "vsview2.ocx"
I want to add these two ocx controls in vb6 ( 16 bit to 32 bit)
You don't state if you already have the OCX files.
To address your first question on how to add OCX controls to your VB6 project. You need to go to Projects -->Components( CtrlT ) then click the Browse button and navigate to where the OCX is located and select it.
As far as the actual OCX Files are concerned there is a Threed20.ocx that is included on the VB6 install media, I believe it is on Disk 2. There is also a registry file that you will need to run to enable design time use of the control. As far as the vsview2.ocx file is concerned if it is not a 32 bit OCX you will need to contact the vendor, who I believe is ComponentSource to get the proper version if you don't currently have it.
And as far is what is a .frm file it is according to this article
A form holds the description of all objects and their properties for each form, as well as the basic code that you have written to respond to the events.

OleControl instantiated to wrong type - only when using in Reg Free COM?

I have an ActiveX control (created using C#) that I am adding to a form in Visual FoxPro using late binding. It works without problems when I register the control.
I want to use reg free COM and created necessary manifest files. Now it load and displays in an inactive state until I double click or grammatically activate it. I don't think it has anything to do with the reg free com manifest files. However is there something I need to do to set it up before/after making the late binding call AddObject()?
this.AddObject('OleControl1', 'oleControl', 'SomeCompany.SomeOleControl')
When I check the OleTypeAllowed Property of the OleControl created by AddObject() it is 1 (Embedded OLE object) instead of -2 (ActiveX object). So the OleControl got instantiated to the wrong type.
I also tried the following:
DEFINE a subclass of OleControl and set the property OleTypeAllowed = -2. Used late binding to load the control. It did not work as required. The OleTypeAllowed came back as 1
Registered the ActiveX control. Added the ActiveX control to the project as a subclass using the visual editor. Unregistered the control. Used late binding to load the control. It did not work as required. The OleTypeAllowed came back as 1.
Is it possible to load the OleControl as a ActiveX control?
Any input from VB that I can convert to FoxPro would also be appreciated.
You probably have the miscStatusContent attribute wrong. This a snippet from a VB6 app manifest we deploy:
<file name="External\COMCTL32.OCX">
<typelib tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" version="1.3" flags="control,hasdiskimage" helpdir="" />
<comClass clsid="{9ED94440-E5E8-101B-B9B5-444553540000}" tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" progid="COMCTL.TabStrip.1" threadingModel="Apartment" miscStatus="" miscStatusContent="recomposeonresize,cantlinkinside,insideout,activatewhenvisible,setclientsitefirst">
<progid>COMCTL.TabStrip</progid>
</comClass>
....
</file>
Notice that miscStatus has to be explicitly cleared.
We are using UMMM for manifest creation in our automated builds.

Resources