Within Windows, what explicitly happens when I double-click on a file in Windows Explorer?
A very common failure mode, and present in your code, is not setting the ProcessStartInfo.WorkingDirectory properly. A subset of programs rely on Explorer setting the default working directory to the directory that contains the file and fall over when it isn't set. They'll do something unwise like trying to open a config file without specifying the full path name, that only works if the working directory is set correctly.
You fix it like this:
Process p = new Process();
p.StartInfo.FileName = file;
p.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(file);
p.Start();
Which assumes that you don't make the same mistake of not specifying the full path name for file.
What are the exact, low-level kernel & OS calls that are being executed when a user either double-clicks or selects a file and presses the Enter key from within Windows Explorer?
You can test it yourself. Here is how I did it: a sample C# program code
class Program
{
static void Main(string[] args)
{
}
}
Now you can run this application from a predifined location. You can then use a ProcMon application from SysInternals to observe the low-level calls. Here is a snapshot of csv file that was generated by ProcMon on my machine. I have put a filter only to include path
to the file, which was c:\test.exe
"Time of Day","Process Name","PID","Operation","Path","Result","Detail"
"14:57:55.3495633","Explorer.EXE","2568","CreateFile","C:\Test.exe","SUCCESS","Desired Access: Generic Read, Disposition: Open, Options: Open Requiring Oplock, Attributes: N, ShareMode: Read, AllocationSize: n/a, OpenResult: Opened"
"14:57:55.3498808","Explorer.EXE","2568","FileSystemControl","C:\Test.exe","SUCCESS","Control: FSCTL_REQUEST_FILTER_OPLOCK"
"14:57:55.3507711","Explorer.EXE","2568","CreateFile","C:\Test.exe","SUCCESS","Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened"
...
Full version of csv is available on pastebin. Every line in the csv file corresponds to a low level call, plus there is other fluff which was excluded due to the strict filter on path.
You "TL;DR" question is brief and to the point but I'm not sure answering that question will solve your problem. Hans Passant's answer is probably much more useful. Nevertheless I will try to provide a little information.
Windows has several layers and in this case the two interesting layers are the Windows Shell API and the System Services API. You are using Process.Start()
in a way that will call ShellExecuteEx
in the Windows Shell. The Windows Shell provides an abstraction on top of Windows where you have a desktop (which really is a folder on some disk) and files are treated as documents with icons and verbs to operate on these documents. In your case you are using the Open
verb.
The Windows Shell is quite complex and can be extended so what ShellExecuteEx
is doing for a particular path and verb is note easy to answer. It depends on the what is registered on the local machine. However, if the file is a PDF file and the verb is Open
you would expect that the shell would run whatever application is associated with the .PDF
extension in the registry.
In Windows 7 you can examine and modify the file assocations at Control Panel > Programs > Default Programs > Set Associations. I suspect that if the program associated with the .PDF
extension is missing you may get FileNotFoundException
but I haven't verified that.
If the shell decides that an application should be executed it will at some point call the System Services layer and use the CreateProcess
function to create a new process. For a PDF file (depending on the registration for .PDF
) a process executing Acrobat.exe
with a single command line argument (the file you specified) will be created.
To troubleshoot the issue you can at a command prompt write file.pdf
(the file should exist) and see if the shell is able to open a PDF file.