How do I launch a file as if it were a text file, even though its extension is not .txt?

You might have a program that generates log files or other text content with an extension other than .txt. You naturally might want to open these documents in the user's default text editor.

You might decide to ask the Windows developer support team, "How can I figure out what program is the handler for text files?" The idea being that once you get this program name, you can then run it yourself, with the document on the command line. And you would also be running into the trap of looking for the answer to a question rather than a solution to a problem.

For one thing, the default handler for the file type might require special command line parameters, parameters which you won't get if you merely get the executable path. For example, on Windows 7, the default command line for JPG files is %SystemRoot%\System32\rundll32.exe "%ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll", ImageView_Fullscreen %1, and if you merely asked for the executable, all you would get back would be rundll32.exe, and trying to execute rundll32.exe Boats.jpg doesn't get you very far. You lost all the command line arguments.

For another thing, the default handler for the file type might not even be a command line. It might be an old program that uses DDE. Or the handler might be a drop target. Or it could be an IContext­Menu or an IExecute­Command. In these cases, there is no command line in the first place, so asking for the command line template is meaningless.

But we saw the answer to this question before, just in a different guise. The lpClass member of the SHELL­EXECUTE­INFO lets you open a file as if it were another type of file. In that article, somebody was passing a class when they didn't mean to; here, we're passing it on purpose.

Comments (18)
  1. laonianren says:

    Or you could register your file extension with the ProgID "txtfile".

  2. Dan Bugglin says:

    Of course if you do something like this the user still won't be able to open the actual log file by clicking on it.

    Sometimes the simplest solution is the best: Give the file an appropriate extension that matches its contents and trust the file associations to match the user's preferences.  In this case, .log files are associated with Notepad by default (IIRC they might even be considered to be class txtfile).

    [Consider the case where you want to open default.html file in the user's preferred text editor. You didn't choose the extension, and you don't want to modify the default association for *.htm either. -Raymond]
  3. saveddijon says:

    And which text editor?

    Notepad chokes on files with Unix line endings. You need to open these in WordPad. Or install a real text editor on your system…

  4. pc says:

    Wouldn't you actually want to open default.html is the user's default HTML editor? So shouldn't you just be invoking the Edit action on the html file rather than the default Open action?

    [View Source is not the same as Edit. -Raymond]
  5. Joshua says:

    @saveddijon: That only works right up through Windows Vista. Starting on 7 that can induce extra linebreaks on long lines.

    Basically these days if you want to deal with .txt files with other line endings you have to ship an editor. Notepad++ is a very good choice due to its licensing. The only real gotcha to just shipping it in its installer is you have to make a configuration option to change the editor.

  6. JDP says:

    And which text editor?

    This whole post was about invoking a user's default handler for a type. Why is "And which text editor?" even a question you'd ask?

  7. Marc says:

    Hooray for Nodepad++ – Let's you right click on any file and open it.

  8. xpclient says:

    Does this work for secondary verbs?

  9. John Ludlow says:

    And why wouldn't the response to such a question be "Do you want arguments with that?"?

  10. Jon says:

    "And why wouldn't the response to such a question be "Do you want arguments with that?"?"

    Because even if you give the customer a way to get the answer with arguments, they're still doing things the wrong way. There are tons of ways for bugs to creep into their parser/argument replacement code, when they really should be using a completely different and much simpler solution.

  11. jon says:

    I notice the docs for SHELLEXECUTEINFO still don't say what the lpClass member is actually for. They say what it should look like, but not why you would want to use it. Would it really kill Microsoft to provide a bit of background information in their documentation?

  12. Csaba Toth says:

    A connecting issue: there's a software which handled entities with attachments. Attachments like what you can have with an e-mail. The user wants to open and edit these attachments. From the software point of view this would mean:

    1. Extract the attachment file to a temporary location.

    2. Spawn the registered editor for the particular file.

    3. Let the user edit the file. And here comes the tricky part:

    4. Get some kind of notification, when the user closes the editor!

    I couldn't tackle the last one. In this case it would be _really_ handy to get hold of the process which edits the file. It is absolutely valid user requirement to be able to do that, but……/invalidoperationexception-if-the-process-is-started-as-a-default-associated-prog

    [Since Windows provides verb handlers enormous flexibility, there is no way to know when the user has finished editing the file (or more generally, when a verb action is complete). -Raymond]
  13. Thanks Raymond, I see that you mention DDE, DropTarget, etc…

  14. Silly says:

    Two simple steps to solve this problem; both taken from this blog!

    Step 1. Programatically change the user's default text editor to notepad.exe. Reference:…/9193695.aspx

    Step 2. swprintf_s( commandLine, L"C:\Windows\notepad.exe "%s"", filePath ) –> CreateProcess( commandLine … ). Reference:…/9954432.aspx


  15. bhind says:

    I remember that I got arguments of rundll32.exe using assc/ftype command in JAVA…(not product

  16. Anonymous Coward says:

    Csaba Toth, 7-Zip falls victim to this problem. If you want to play a music file inside an archive, and you try to do so by double clicking the file while Media Player is already running, 7-Zip deletes the temporary file before Media Player can play it.

    It would be really nice if instead of giving Media Player a file name, you could give it a handle to a (real or virtual) file and get notified when Media player is done with it (the final reference to the handle is closed).

  17. AC says:

    The "proper" solution for that (for very over-engineered enterprisey values of proper) probably is to mount the archive file in a virtual file system and give the media player a file name inside of that.

  18. AC2 says:

    @AC: That's a terrible suggestion. The archive would then be locked by handles, a far too common problem in windows.

Comments are closed.