How to set an application as the default program of opening a certain type of file programmatically? - windows

There's an executable file generated from my program in MFC and I want to use it as the default program to open the .jpg files. That is to say, each time I double click a .jpg file, my program will run.
I tried to add some registry entries linking .jpg files with my program, such as HKEY_CLASSES_ROOT\.jpg\shell\open\command (set its value to "myProgram.exe" "%1"), and HKEY_CLASSES_ROOT\myProgram.
The method works just fine except when some other applications register themselves to open the .jpg files. For example, I have installed acdSee on my computer, so each time I doule click a .jpg file, it always start acdSee instead of my own program. But when I register a completely new type of file with my program, it can be open in the program. I don't know how to set my program as the default opening program of an already registered file programmatically. Can anyone help me solve this problem? Thank you very much!

The more typical/standard way for doing this is to set the default value of the ".jpg" key to a name that identifies the file type more clearly, and then setup the various associated actions there. So for jpgs, you might do this:
HKCR\.jpg
#default = MyApp.JpegImage
HKCR\MyApp.JpegImage\shell\open\command
#default = "myApp.exe "%1""
If some other program decides to register the type, they will replace the default value for HKCR.jpg with some other value, like OtherProgram.Jpg. At that point, you could re-register it to your app by setting the value back to MyApp.JpegImage.
Disclaimer: When making this sort of change, please also try to respect the user's preferences. For instance, when installing your application, give the user the option to set this file association or not set it. You can also provide a command from inside your installed application to reset the associations, if the user should wish to do so.
If you instead wanted to add some additional commands to an existing registered type, you would read the default value of the .jpg key to find the name of the file type. Then you could open that key and add an action to the existing set of actions. For instance, you could add the following:
HKCR\ExistingApp.JpegImage\shell\myopen\
#default = "Open with MyApp"
HKCR\ExistingApp.JpegImage\shell\myopen\command\
#default = "myApp.exe "%1""

Note that by writing a key to HKCR, you're actually writing to HKLM\Software\Classes. This will require administrative privileges. However, you can make per-user changes within a user context by writing your keys to HKCU\Classes\Root instead.
Also, user preferences in HKCU will override the system defaults in HKLM, which sounds like what your problem might be.
This is when a program has not registered an extension as a "Default" (Is the program listed in Set Programs and Defaults in the Control Panel?)
Time to start reading documentation!

Related

Opening a file **in** a batch file

I have a batch program that can be used for opening a specific file format I created. The file format is a actually a zip file with the .zip changed to .gcif.
When you run my btch file there is an input field for entering the location of the .gcif file you want to open. The .gcif is then renamed to .zip. The 7z.exe (which is in the same directory as the batch file) then unzips the file and it is processed by my batch file.
But I would like it to also work when the user finds any .gcif file, right clicks it, and selects Open With my batch file. Is there any way for batch file to detect that ithas been tasked to open that specific file?
I figured it out. When a file is opened with a batch file, the file location is passed on to the batch file as a parameter. The parameter can then be accessed using %1.
For example, if I opened the file C:/document.txt in a batch file containing this code:
#ECHO OFF
ECHO %1
The output would display C:/document.txt.
You can register a windows file handler in your system.
You might need admin rights and might need to modify the registry.
Essentially you "connect" your filextension .gcif with your batch file so windows knows that any file of this extension is connected to your batchfile
You can read something about it on the msdn site here: How to Register a File Type for a New Application
If you plan to associate one or more file types with a new
application, you must define a ProgID for each file type that you want
to associate with the application.
To create a ProgID for each unique file type that your application
handles, use these steps.
Instructions
Step 1: Note that some file types have multiple
extensions that point to the same ProgID; for example:
HKEY_CLASSES_ROOT\App.jpeg (your ProgID)
HKEY_CLASSES_ROOT\.jpg = App.jpeg (the file type mappings)
HKEY_CLASSES_ROOT\.jpeg = App.jpeg
Step 2:
Remove the ProgID values when you install and uninstall your
program.
Step 3:
Leave the file type mappings unchanged at uninstall time.
Doing so works because file type mappings are stored per user in
HKEY_CLASSES_ROOT.ext, and the system identifies the case where the
ProgID value is missing and ignores it. Leaving file type mappings
unchanged avoids the need to have conditional code that only removes
the file type mapping if the value still points to your ProgID. It is
important to avoid doing so in cases where it might have been changed
by another application and you thus cannot easily remove the value.
Step 4:
Specify a unique value for the file type description of each
file type ProgID by doing one of the following:
Leave the default value of the ProgID empty, in which case the system
uses the .ext file. Provide a localized value via FriendlyTypeName
and, for compatibility with old applications that read the registry
directly, be sure to provide the default value of the ProgID as the
file type description (that is, use the same value that is referred to
by the FriendlyTypeName in the English resource). Remarks If you plan
to associate the file with an existing application, locate an
application ProgID in the registry.
To accomplish something similar you can open your file once with Explorer and chose "Open with..." - locate your batch file and choose "always open with this application" checkbox.
The first option here is more for when you want to provide 1-click-open experience to customers for your application when they install it on their system.

Can the last opened file location be directly altered?

As I understand it, when a file open dialog box (such as GetOpenFileName) is used, Windows will automatically remember where the last file was that was opened by the program, and Windows remembers these locations separately for each program. Is there a way to directly alter this, in order to cause the file picking dialog for program X to start in C:\Example\Directory?
I'm attempting to automate a program which has been programmed to work only through a GUI, and I don't have any access to the internals of this program (such as being able to alter how it calls the file picker). Instead, I'm using a mouse macro (via AutoHotkey). If I can be completely sure that the file picker will start in a particular place, I should be able to automate the rest with mouse clicks.
If you had access to the source code, I'd suggest you just change the lpstrInitialDir property of the OPENFILENAME passed to GetOpenFileName().
Outside of that, you'll want to change the registry keys for the MRUs:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32
What might make more sense, and might fix the issue you're having, is also changing the Working Directory so that the default location isn't "My Documents", if you're experiencing that.
Depending on the operating system, the results vary:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx

How to add an entry in the Windows context menu for files with a specific extension?

I know that many questions are asked about how customizing the shell context menu, but what I've tried yet doesn't work so I'm adding a new question.
I'd like to add an entry "Open with Log Viewer" in the context menu when right-clicking on files with ".log" extension, to not change the default application associated with .log files (notepad) but allow the user to choose a custom application to open them.
To do this, I opened the registry key HKEY_CLASSES_ROOT\.log, and added some keys shell\OpenWithLogViewer\command with the correct values, but the entry is not displayed when I right-click on a file with .log extension.
Would you know how to fix this?
The key HKEY_CLASSES_ROOT\.log has for default value txtfile, and contains a subkey called PersistentHandler. Can this subkey be the origin of the problem?
Add another registry key (e.g. HKEY_CLASSES_ROOT\logfile), create the shell structure below that key and change the default value of the .log key to logfile. One way to do this is by saving the following lines to a .reg file and merging that file into the registry.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.log]
#="logfile"
[HKEY_CLASSES_ROOT\logfile]
[HKEY_CLASSES_ROOT\logfile\shell]
#="OpenWithLogViewer"
; make OpenWithLogViewer the default action
[HKEY_CLASSES_ROOT\logfile\shell\OpenWithLogViewer]
#="Open with &Log Viewer"
; set label and access key
[HKEY_CLASSES_ROOT\logfile\shell\OpenWithLogViewer\command]
#="\"C:\\path\\to\\logviewer.exe\" %1"
This separates the type (logfile) from the extension (.log). That way you can define the possible actions for a type in one place and associate arbitrary extensions with that type.
Note that you can also define this on a per-user basis by using HKEY_CURRENT_USER\Software\Classes instead of HKEY_CLASSES_ROOT. User entries take precedence over system entries. This is useful when you want to change file associations or add custom actions for your own user, but don't have admin privileges on the system.
If you want to add a entry for a file extension you don't "own" and you never want to be the default action then you can use the SystemFileAssociations key:
[HKEY_CLASSES_ROOT\SystemFileAssociations\.log\shell\mycommand]
#="My Command"
[HKEY_CLASSES_ROOT\SystemFileAssociations\.log\shell\mycommand\command]
#="\"c:\\path\\myapp.exe\" \"%1\""
To deal proactively with the consequences of a change to default programs, you can use HKEY_CLASSES_ROOT\SystemFileAssociations to register verbs and other association information. Due to their location after the ProgID in the association array, these registrations are lower priority. These SystemFileAssociationsregistrations are stable even when users change the default programs, and provide a location to register secondary verbs that will always be available for a particular file type.
This key is available on Windows XP and higher...

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.

How does the OS know what to do with a file when the "Open With..." option is selected?

Explanation:
I don't remember about Linux and I don't know about OS X, but in Windows you can right-click a file and select a program to open it. But how does the OS know exactly how to make the program open it? Does it keep track of the "Open file" dialogs the program has? Does the developer have to specify a special event handler or something for these cases?
For Windows, the answer is in the registry. If you're comfortable reading the registry, run regedit.exe on your Windows machine.
Under HKEY_CLASSES_ROOT, you will see a key list of all file types, .doc, .txt, etc. Each of these keys contains a key called "OpenWithList" or "OpenWithProgIds". An application may have a registered "ProgId", also found under HKEY_CLASSES_ROOT, and it can register it's ProgId to the file types it wants to handle in OpenWithProgIds. Otherwise it registers itself in OpenWithList.
In response to the comment to the first answer (cos I don't have enough rep to comment):
You're thinking of DDE, which is a near-enough deprecated technology. The Windows shell executes the application with the selected file as the first parameter.
The Windows Explorer remembers your previous "Open With..." choices based on file extension in the following key:
HKCR\.ext\OpenWithList
Next time you right-click the file, it looks there and build a list of programs you have previously used to open a particular file type.
Say it finds a key named "myapp.exe". It then looks up the application here:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Applications\myapp.exe
fetches the info where the application is installed. And it goes here:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\myapp.exe
follows the GUID stored there to find out the display name of the application.
To add to the fun, the primary associated application is in the list as well, also everything in the OpenWithProgIds key and everything in:
HKEY_CLASSES_ROOT\*\OpenWithList
as well as their respective HKEY_CURRENT_USER counterparts.
The resulting list of applications is then made unique, sorted and displayed. On selection the file is started like any other file you click on - i.e.:
C:\path\to\myapp.exe "C:\path\to\the\file.ext"
http://windowsxp.mvps.org/OpenWith.htm
File associations are stored in the Registry in: HKEY_CLASSES_ROOT.
You can manage them graphically by using Windows Explorer: (WinXP)
Click Tools/Options/File Types
Or with the "Default Programs" applet in Control Panel. (Vista)
Just for some nostalgia the rather brilliant Acorn archimedes had a much better system with each file type having a unique type number, with a manufacturer and application code (rather like a MAC address) which was written with the file.
This means you can have different files all called .bak opened by the correct application - unlike the windows case where a new installed app steals the ownership of every exiting file of that type. Autocad is especialy bad for this, registering about 20 file types.
The operating system runs the specified program sending as parameter the path of the file to open.
For example, in C#, if you want to know which file the operating system wants you to open you'll need to do:
class Program
{
static void Main(string[] args)
{
if (args.Length == 1) //The OS wants me to open a file
openSomeFileJustBecauseTheOSWantsIt(args[0]);
}
}

Resources