コンソールアプリケーション(Fortranで書かれています!)であるexeプロセスの実行を処理するクラスがあります。このプログラムを実行するとき、ユーザーは最初に入力ファイル(exeと同じ場所に存在する必要があります)と出力ファイル(まだ存在していませんが、exeによって生成される)の名前を入力する必要があります。
Executeメソッドの単体テスト(以下を参照)では、すべてが正常に機能します。出力ファイルは正しく作成されます。ただし、MVCアプリケーションからこのメソッドを実行すると、入力ファイルが存在していても、exeは入力ファイルを見つけることができません。これについて私が考えることができる唯一の説明は、VS2010によって自動的に作成された「TestResults」フォルダーがアクセス許可の点で何らかの形で異なるか、単体テストプロセスが何らかの形で異なるということです。
public void Execute(string inputFileName, string outputFileName, int timeoutMilliseconds)
{
if (outputFileName == null)
throw new ArgumentNullException("outputFileName");
else if (inputFileName == null)
throw new ArgumentNullException("inputFileName");
if (outputFileName == string.Empty)
throw new ArgumentException("outputFileName must not be an empty string");
else if (inputFileName == string.Empty)
throw new ArgumentException("inputFileName must not be an empty string");
if (!File.Exists(ConfigurationManager.AppSettings["dataPath"] + inputFileName))
throw new FileNotFoundException("File not found.", inputFileName);
Process p = new Process();
p.StartInfo = GetProcessStartInfo();
p.Start();
string output = "";
// Read up to line where program asks for input file name.
while (output == "")
output = p.StandardOutput.ReadLine();
// Write the input file name.
p.StandardInput.WriteLine(inputFileName);
// Read up to line where program asks for output file name.
output = "";
while (output == "")
output = p.StandardOutput.ReadLine();
// Write the output file name.
p.StandardInput.WriteLine(outputFileName);
if(!p.WaitForExit(timeoutMilliseconds))
throw new ApplicationException("The process timed out waiting for a response.");
}
private ProcessStartInfo GetProcessStartInfo()
{
var startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.FileName = _exeFileLocation;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
return startInfo;
}
編集:
Cドライブ上の場所からプロセスを実行しようとすると、単体テストも失敗することがわかりました。以下のコードで、「dataPath」をハードディスクの場所(「C:\ DATALOCATION」など)に設定すると、プロセスは失敗し、入力ファイルが見つからないと表示されます。ただし、構成の「dataPath」を空の文字列のままにすると、単体テストはTestResultsフォルダーのサブディレクトリからプロセスを自動的に実行し、すべてが機能します。
[TestMethod]
public void ExeRunnerTest()
{
var studyData = // populate study data here
var writer = new StudyDataFileWriter(studyData);
// Write input
string fileName = writer.WriteToFile();
// Run
var exeRunner = new ExeRunner(ConfigurationManager.AppSettings["dataPath"] + "myProcess.exe");
exeRunner.Execute(fileName, "outputFile", 10000);
// Read output
IStudyOutputFileReader reader = new StudyOutputFileReader(ConfigurationManager.AppSettings["dataPath"] + "outputFile");
StudyOutput output = reader.Read();
// Tests
Assert.AreEqual(1, output.ConsumerSummary.ConsumerTypes.Count());
}