0

コンソールアプリケーション(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());
    }
4

1 に答える 1

0

絶対パスを使用すると、コードが機能しました。作業ディレクトリに問題があったに違いありません。

于 2012-09-28T11:28:46.377 に答える