When you use the open with option on a file within Windows, how is this carried out? I am wondering because I would like to "open" picture files by handing them to my program via argv[], but unsure if the "open with" option works in this manner.
Printable View
When you use the open with option on a file within Windows, how is this carried out? I am wondering because I would like to "open" picture files by handing them to my program via argv[], but unsure if the "open with" option works in this manner.
Open with brings up a shell dialog that allows you to select which program opens a given file.
Basically it creates a file association in the User's settings.
You can create these manually but it's not a one call process and it's generally not used with Console programs (although it can be)...
File Types and File Associations (Windows)
Here's an example, it's reliant on some external defines but I think you can get the general idea from it....
Code:// add server approved entries
VOID NetAddFileType(PTCHAR Type)
{ TCHAR vn[MAX_PATH]; // string for verb keys
TCHAR vt[MAX_TYPENAME + 16]; // verb text
TCHAR cl[MAX_PATH]; // command line
DWORD ts; // time stamp value
HKEY reg; // type name ckey
if (wcslen(Type) < 2)
{ ShowMessage(100);
SHChangeNotify(SHCNE_ASSOCCHANGED,0,0,0);
ts = time(NULL);
SHSetValue(REG_HIVE,REG_UPDATE,Server.Name,REG_DWORD,&ts,sizeof(ts));
return; }
// compose command line
GetModuleFileName(NULL,cl,MAX_PATH);
PathQuoteSpaces(cl);
wcscat(cl,L" -S:");
wcscat(cl,Server.Name);
wcscat(cl,L" \"%1\"");
// create verb string
swprintf(vn,MAX_PATH,L"Shell\\ROPEN_%ls",Server.Name);
// create verb text
swprintf(vt,MAX_PATH,L"Launch on %ls",Server.Name);
// make first key
if (!AssocQueryKey(ASSOCF_NOFIXUPS | ASSOCF_INIT_IGNOREUNKNOWN,
ASSOCKEY_CLASS,Type,NULL,®))
{ SHSetValue(reg,vn,NULL,REG_SZ,vt,StrSize(vt));
wcscat(vn,L"\\Command");
SHSetValue(reg,vn,NULL,REG_SZ,cl,StrSize(cl));
RegCloseKey(reg); } }
Code:KEY_CLASSES_ROOT
SystemFileAssociations
text
shell
edit
command
(Default) = "%SystemRoot%\system32\NOTEPAD.EXE" "%1"
open
command
(Default) = "%SystemRoot%\system32\NOTEPAD.EXE" "%1"
So I have the assumption if I set up my program in the registry and set it up to run similar to:
"%SystemRoot%\system32\MYPROGRAM.EXE" "%1"
The %1 is the filepath/name being passed to MYPROGRAM.EXE as argv[1] ?
Sorry but, not even close....
First you need call a shell function that traces the association from the ".XYZ" file type to it's HKEY_CLASSES_ROOT PID (Program ID)... this gives you a registry key... Within that registry key you need to create a new shell verb ... It gets complex when you realize there are multiple sources for file associations... There are the global ones in HKEY_CLASSES_ROOT but there are also more, user defined ones, in HKEY_CURRENT_USER\software\microsoft\windows\curre nt version\explorer\fileexts so you don't actually know which PID is connected to which file extension, at least not in any simple way...
Take a look at this in RegEdit... look at the HKEY_CLASSES_ROOT extension list... see any program paths there? Typical of Microsoft they just HAD to do this in the most bassackward way possible...
The file path has to be the last argument in a windows command line... so you will need to handle things like
Plus the filename will arrive quoted if there are spaces, but may not be quoted if there are no spaces.Code:"c:\program files\my magic\magic.exe" -s -l /q "%1"
"c:\program files\my magic\magic.exe" /my:flags "%1"
...
Windows provides a few tools for this... PathUnquoteSpaces(), PathFindArgs(), PathIsDirectory(), PathExists() etc.
I don't run Windows so it's not easy for me to mess with =/
I am trying to port a program I am writing over to Windows, but most Windows users don't want to run things via command line. The program will be a replacement photo viewer (faster and simpler than Windows' photo viewer). I want to be able to open picture extensions within my program automatically. I guess it's going to take quite a bit of Windows learning *cringes*.
A properly configured windows system should never require a user to do anything but click on files... except for the case of creating a new file, in which case the user is supposed to go to the start menu and run the program.
For what it's worth... Windows does provide function calls for this, as I've shown you... AssocQueryKey() gets you the root PID to put your shell verb in... SHSetValue() is how you write the new registry keys. You have to build the sub-tree layer by layer, there is no way to write it all at once.
"Open with <program name>" is a typical text identifier and the registry tree at that point looks like this:
This has to be repeated for each file extension you wish to open. You should never change an existing key that is created by anything but your own program.Code:HKEY_CLASSES_ROOT <PID> <--- this is the registry key returned by AssocQueryKey()
Shell <-- text is the default action "Open", "Print", etc. from the list below
Open <-- Shell verb, what to do. Text is a description of the action
Command <-- text is the command line for your program.
<-- you have to create the following programatically
Open_MYVIEW <-- user verb, text is "Open With MyView" or such.
Command <-- default text is your program's command line...
When you right click you will see "Open with MyView" on the menu... clicking that should launch your program.
To make your viewer the default, following the example above, you would set the default text for the Shell key to "Open_MYVIEW".
Thanks, that's not too bad. I actually wrote some registry stuff before to make a program autorun with Windows and hide the files within the system32 folder (a keylogger I wrote for security class). I am new to this though! Thanks~
You can see the general form...
Take a look at HKEY_CLASSES_ROOT in Regedit...
Find a file type such as .MP3 look inside...
it should say something like MPLAYERC.MP3 (provided you're using Media Player Classic)
Next look at MPLAYERC.MP3 in the same list...
It will have the Shell\Open\Command sequence
So what AssocQuerryKey is doing is giving you a handle to the MPLAYERC.MP3 PID... Which is where you want to add your own Shell\<verb>\Command branch.
The complication comes in that not all users will use the global association in HKCR... so the AssocQueryKey() also checks for user associations and will return errors if there is no association...
Your software should give the user some way of deciding which files it does and doesn't open... This is usually done with a dialog and checkboxes... when the dialog is closed, you write the new associations, keeping in mind that if some users have already chosen their own, your custom verb may or may not already exist... or it may end up in two different places.
Not to discourage you but... setting autorun is child's play beside this one.
Thanks!! I see what is going on. I will keep at it~