Thread: Windows' "Open with" option...?

  1. #1
    Registered User \007's Avatar
    Join Date
    Dec 2010
    Posts
    179

    (solved) Windows' "Open with" option...?

    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.
    Last edited by \007; 01-18-2011 at 08:45 AM.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    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,&reg))
          { SHSetValue(reg,vn,NULL,REG_SZ,vt,StrSize(vt));
            wcscat(vn,L"\\Command");
            SHSetValue(reg,vn,NULL,REG_SZ,cl,StrSize(cl));
            RegCloseKey(reg); } }  
     
    Last edited by CommonTater; 01-18-2011 at 08:36 AM. Reason: Bolded the crucial part....

  3. #3
    Registered User \007's Avatar
    Join Date
    Dec 2010
    Posts
    179
    Quote Originally Posted by CommonTater View Post
    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)
    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] ?

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by \007 View Post
    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
    Code:
    "c:\program files\my magic\magic.exe" -s -l /q "%1"
    "c:\program files\my magic\magic.exe"  /my:flags "%1"
    ...
    Plus the filename will arrive quoted if there are spaces, but may not be quoted if there are no spaces.
    Windows provides a few tools for this... PathUnquoteSpaces(), PathFindArgs(), PathIsDirectory(), PathExists() etc.
    Last edited by CommonTater; 01-18-2011 at 08:16 AM.

  5. #5
    Registered User \007's Avatar
    Join Date
    Dec 2010
    Posts
    179
    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*.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by \007 View Post
    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:
    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...
    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.

    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".
    Last edited by CommonTater; 01-18-2011 at 08:38 AM.

  7. #7
    Registered User \007's Avatar
    Join Date
    Dec 2010
    Posts
    179
    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~

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by \007 View Post
    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.

  9. #9
    Registered User \007's Avatar
    Join Date
    Dec 2010
    Posts
    179
    Thanks!! I see what is going on. I will keep at it~

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Network Programming in C for Windows
    By m.mixon in forum C Programming
    Replies: 7
    Last Post: 06-19-2006, 08:27 PM
  2. LoadFromFile() causes Windows 98 to freeze?
    By MidnightlyCoder in forum Windows Programming
    Replies: 8
    Last Post: 03-17-2006, 02:23 PM
  3. IE 6 status bar
    By DavidP in forum Tech Board
    Replies: 15
    Last Post: 10-23-2002, 05:31 PM
  4. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM
  5. shutting down windows
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 01-02-2002, 12:28 PM