ProcessStartInfo.WorkingDirectory Ignored
I have a previously working program, currently built with VS .NET 2008 with SP1, that starts a process to run a batch file in the context of a particular working directory. This program is now failing on my machine as well as at least one other in our organization. On other machines, it succeeds. I thought I had narrowed the difference between systems down to the fact that the machines on which it did run correctly all seemed to be lacking SP1 for .NET Framework 3.5. However, I then came across a machine on which SP1 was installed, but which still ran the program OK.
The problem has to do with the use of the WorkingDirectory property of ProcessStartInfo. Normally, setting this, when UseShellExecute is set to true, will cause the started process to work in the context of the specified directory. The issue I'm seeing is that, on the problem machines, WorkingDirectory seems to be completely ignored. Here are steps for replicating the problem:
1. Compile the following console app, called CallCmd:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;
namespace CallCmd
{
class CallCmd
{
private static string file = "foo.cmd";
private static string folderName = "C:\\foobar\\";
private static Process myProcess = null;
static void Main(string[] args)
{
ProcessStartInfo startInfo = null;
startInfo = new ProcessStartInfo("\"" + file + "\"");
startInfo.CreateNoWindow = true;
/* Note:
* When UseShellExecute is true, the WorkingDirectory
* property specifies the location of the process that
* is being launched by Process.Start().
*/
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = folderName;
myProcess = new Process();
myProcess.StartInfo = startInfo;
// Run the process.
myProcess.Start();
}
}
}
The important line in this program is:
startInfo.WorkingDirectory = folderName;
where folderName is "C:\\foobar\\" in the class definition.
2. Copy the CallCmd.exe to some folder on your path. (Note that it must not be in the folder created in the next step .) I put it in \Windows\System32.
3. Make a directory called "c:\foobar" and create two .cmd files in it. The first is foo.cmd, which contains this:
@rem ----------------------------------------------------
@rem foo.cmd
@rem ----------------------------------------------------
@echo off
echo --------------------------------------------- > out.txt
echo Inside of FOO.CMD >> out.txt
echo --------------------------------------------- >> out.txt
chdir >> out.txt
call bar %1 %2 %3 %4
The second is bar.cmd, which contains this:
@rem ----------------------------------------------------
@rem bar.cmd
@rem ----------------------------------------------------
@echo off
echo --------------------------------------------- >> out.txt
echo Inside of BAR.CMD >> out.txt
echo --------------------------------------------- >> out.txt
chdir >> out.txt
Note a couple of things about these batch files. First, foo.cmd calls bar.cmd without a path specified, assuming that they are both in the same folder. Secondly, the chdir command, without a path argument, simply prints whatever the command shell thinks is the current working directory.
4. Now, at a command prompt, cd to the c:\foobar directory and execute the program "CallCmd", which should be in another folder that is on your path.
On machines where the bug occurs, this is the behavior:
- There is NO out.txt file created in the current folder, c:\foobar.
- There IS a file with this name created in the root C:\ folder!
- if yout "type c:\out.txt", this is what you will see:
---------------------------------------------
Inside of FOO.CMD
---------------------------------------------
C:\
In other words, the bar.cmd file was not found (because the process invoked in CallCmd.exe has not been able to set the working directory to "c:\foobar", where bar.cmd is located. Furthermore, the actual working folder is for some reason believed to be the root folder, as is proven by the fact that out.txt appears in that folder and the chdir command in foo.cmd wrote "C:\" to the output file.
On a machine without this bug, you will see the expected behavior, that is, out.txt is created in the c:\foobar folder, and bar.cmd is called by foo.cmd so that out.txt ends up containing this text:
---------------------------------------------
Inside of FOO.CMD
---------------------------------------------
C:\foobar
---------------------------------------------
Inside of BAR.CMD
---------------------------------------------
C:\foobar
So far, I can only say that all the machines I've found to be free of this bug are running .NET 3.5 without the SP1 applied. The converse, however, has been shown to not always be the case. (That is, as mentioned above, at least one SP1 machine is able to run the program correctly.
Although I'm not sure why it isn't happening everywhere, I see this is a very serious defect in the framework, since it has the effect of running a process in the wrong directory, which could have very nasty results indeed.
Any theories about this would be greatly appreciated.
Mark Zudeck
Torto Wheaton Research
|