22
votes

Is there a simple way to open a file by its associated program in windows? (like double clicking it in windows explorer but done automatically with my code)

For example, on computer A, "text.txt" will be opened in wordpad but on computer B it will be opened by Notepad++ because of the users file extension assignments.

I tried ShellExecute

ShellExecute(0, L"open", L"c:\\windows\\notepad.exe" ,L"c:\\outfile.txt" , 0 , SW_SHOW );

which works but if I omit the notepad.exe parameter weird things happen (a random explorer is shown).

6
If you already got it working, what's the question?David Grayson
The OP did not "get it working". This "working" version only opens files with notepad. The intent is to get the operating system to open the file with the file's associated program, not necessarily notepad.RufusVS

6 Answers

30
votes

You want to use the file to open as the file argument, not the parameter argument. No need to specify which program to use, ShellExecute will look it up for you.

ShellExecute(0, 0, L"c:\\outfile.txt", 0, 0 , SW_SHOW );

By leaving the verb as NULL (0) rather than L"open", you get the true default action for the file type - usually this is open but not always.

5
votes

See Launching Applications:

ShellExecute(NULL, "open", L"c:\\outfile.txt", NULL, NULL, SW_SHOW);

On windows, a good memory hook is to think of all data-files being executable by the shell. You can also try it out in a command box, where you can just type a filename, and it will be opened up. Or, the other way around, every file in Windows can be opened, and the default opening-action for executable files is to execute them.

2
votes

According to the MS Knowledge Base, ShellExecute should work (we do this in Delphi all the time):

ShellExecute(Handle, "Open", Filename, "", "C:\", SW_SHOWNORMAL)
2
votes

A little more possibilities here:

If you want to open - for example - the file by default with Notepad++ (if installed), you could scan for it's registry key if it exists and where it is, (Usually HKLM\SOFTWARE\Wow6432Node\Notepad++ [tested Win7]) then take that path and open it.

std::wstring file = L"C:\\Outfile.txt";

if (NotepadPlusPlusExists()) //Open with Notepad++ or use an other program... (maybe your own ?)
{
    std::wstring wsNPPPath = GetNotepadPlusPlusPath();
    ShellExecuteW(HWND, L"open", wsNPPPath.c_str(), file.c_str(), NULL, SW_NORMAL);
}
else //Open with default associated program <---
    ShellExecuteW(HWND, NULL, file.c_str(), NULL, NULL, SW_NORMAL);

If you want the user to be able to change the default program or select a program he/she wants to use, you may open the "Open with" dialog.

//std::wstring StringArgsW(const wchar_t *format, ...);
std::wstring wsCmdOpenWith = StringArgsW(L"C:\\Windows\\system32\\shell32.dll,OpenAs_RunDLL \"%s\"", file.c_str());
ShellExecuteW(HWND, L"open", L"C:\\Windows\\system32\\rundll32.exe", wsCmdOpenWith.c_str(), NULL, SW_NORMAL);

You can also open the file in explorer.

std::wstring wsCmdExplorer = StringArgsW(L"/select,\"%s\"", file.c_str());
ShellExecuteW(HWND, L"open", L"explorer.exe", wsCmdExplorer.c_str(), NULL, SW_NORMAL);
1
votes

If lpFile specifies a document file, the flag is simply passed to the associated application

So you need to substitute "c:\\windows\\notepad.exe" with the actual file you want to open and leave lpParameters null.

0
votes

Maybe try start instead of open?