2013-10-25 20 views
1

我想打电话用简单的代码的应用程序一样进程退出,但实际上不完全

public void Run(string command) 
{ 
    Process proc = new Process(); 
    proc.StartInfo.FileName = "acvTemp.exe"; 
    proc.StartInfo.Arguments = command;    

    proc.Start(); 

    proc.WaitForExit(); 
} 

,文件名过程中,我居然推出产生一个新的窗口。它的一些命令使它无法退出。即

command = acvtest.exe /launch /wait /log:<temp.log> 

所以acvtest.exe启动机器上运行,并且实际上仍在运行,所以我可以运行像

acvtest.exe /getid:<name> 

其他命令这是我将如何手动使用应用程序。

acvtest.exe /launch /wait /log:<temp.log> 
acvtest.exe /getid:<name> 

注意实际/启动过程返回shell命令提示符,因为/启动打开一个新的命令窗口和/的getId的输出实际写入日志。

我的问题是,当第一个/ launch或/ getid命令运行时,即使在日志上释放句柄之前,waitforexit()似乎正在退出。 (可能在某些孩子出口之前?)

也就是说,下面的命令会失败,直到我进入睡眠状态或在两者之间等待。即使waitforexit()

Run("/launch /wait /log:<temp.log>"); 
Run("/getid:<name>"); 
Run("shutdown"); 

//Needs some sleep or wait here 

using (StreamReader reader = new StreamReader("temp.log")) 
{ 
    Console.WriteLine(reader.ReadToEnd()); 
} 

在没有任何睡眠或上述两个部分之间等待,访问日志失败,错误,它已被另一个进程。看起来应用程序在实际完成其进程之前即将退出。这是应用程序的问题吗?我能做些什么来解决它?

我怀疑我可能需要一些不同的Run()代码,因为启动了一个新的shell。

[更新]

问题不仅在于日志文件。当我运行Run(“/ getid:”)时,假设有大约100,000个文件名,其中很多文件名会因'资源不可用'错误而失败,这就是为什么我认为应用程序可能在其释放资源之前退出 谢谢寻找。

+0

做一个循环,尝试之间等待。 – Dialecticus

+0

我在问题结尾添加了更新。谢谢。 – user393148

回答

0

这是应用程序的问题吗?我可以做些什么来在其周围工作 ?

我会说应用程序可能没有任何问题。操作系统本身很可能完全没有完全释放文件。

一个常见的解决方法是将尝试读取Try/Catch块中的文件并将其放在while循环中并延迟,或者从Timer中调用该代码。

+0

感谢您的回复。问题不仅在于日志文件。当我运行Run(“/ getid:”)时,假设有大约100,000个文件名,其中很多文件名因“资源不可用”错误而失败,这就是为什么我认为应用程序可能在其释放资源之前退出 – user393148

+0

在每个Run()命令之间插入一个等待解决方案? – user393148

+0

哈哈......这是你遗漏的一些重要信息!很难说应用程序需要多长时间才能“正常”工作。谁知道它是如何编码的。此外,如果整个系统的条件发生变化,那么以前工作的延迟将不再有效?我认为最好的方法是简单地调整中间睡眠()的延迟时间,然后“祈祷”它始终有效。抱歉。 –

0

提议解决文件锁定问题here。然后您可以提取感兴趣的进程的PID。

然后再次,如果日志文件保持打开状态直到进程退出,那么您的“信号量”就在那里。

0

我想你既可以尝试使用下面的代码

FileStream fs = File.Open("temp.log", FileMode.Open, FileAccess.Read); 

打开该文件为只读,或者你使用像这样的一些代码:

try 
{ 
    // some code here ... 

    // Try to access the file within 1000 (or whatever is specified) ms. 
    FileAccessHelper.WaitForFileAccessibility("test.log", 1000); 

    // and here ... 
} 
catch (FileAccessHelperException e) 
{ 
    // your error handling here... 
    Console.WriteLine("Unable to open the file within 1000ms"); 
} 

的FileAccessHelper类看起来是这样的:

namespace CodingFun 
{ 
    using System; 
    using System.IO; 
    using System.Threading; 

    /// <summary> 
    /// Represents our FileAccessHelper class. 
    /// </summary> 
    public static class FileAccessHelper 
    { 
     /// <summary> 
     /// Blocks until the specified file can be accessed or a timeout occurs. 
     /// </summary> 
     /// <param name="filename">The file which shall be accessed.</param> 
     /// <param name="timeout">The timeout in milliseconds.</param> 
     /// <param name="accessMode">Specifies the file access mode, default is read only.</param> 
     public static void WaitForFileAccessibility(string filename, int timeout, FileAccess accessMode = FileAccess.Read) 
     { 
      int tries = 0; 
      bool readDone = false; 

      do 
      { 
       try 
       { 
        // Try to open the file as read only. 
        FileStream fs = File.Open(filename, FileMode.Open, accessMode); 

        // Close it if it worked and... 
        fs.Close(); 

        // ... set a flag so that we know we have successfully opened the file. 
        readDone = true; 
       } 
       catch (Exception e) 
       { 
        // increase the counter and... 
        tries++; 

        // ... check if a timeout occured. 
        if ((100 * tries) >= timeout) 
        { 
         throw new FileAccessHelperException(string.Format("Unable to access the file {0} within the specified timeout of {1}ms", filename, timeout), e); 
        } 
        else 
        { 
         // If not just sleep 100 ms. 
         Thread.Sleep(100); 
        } 
       } 
      } 
      while (!readDone); 
     } 
    } 
} 

而FileAccessHelperException类看起来像这样:

namespace CodingFun 
{ 
    using System; 
    using System.Runtime.Serialization; 
    using System.Security; 

    /// <summary> 
    /// Represents the FileAccessHelperException class. 
    /// </summary> 
    public class FileAccessHelperException : Exception 
    { 
     /// <summary> 
     /// Initializes a new instance of the <see cref="FileAccessHelperException"/> class. 
     /// </summary> 
     public FileAccessHelperException() 
      : base() 
     { 
     } 

     /// <summary> 
     /// Initializes a new instance of the <see cref="FileAccessHelperException"/> class. 
     /// </summary> 
     /// <param name="message">The message that describes the error.</param> 
     public FileAccessHelperException(string message) 
      : base(message) 
     { 
     } 

     /// <summary> 
     /// Initializes a new instance of the <see cref="FileAccessHelperException"/> 
     /// class with a specified error message and a reference to the inner 
     /// exception that is the cause of this exception. 
     /// </summary> 
     /// <param name="message">The error message that explains the reason for the exception.</param> 
     /// <param name="innerException"> 
     /// The exception that is the cause of the current exception, or a null reference 
     /// if no inner exception is specified. 
     /// </param> 
     public FileAccessHelperException(string message, Exception innerException) 
      : base(message, innerException) 
     { 
     } 

     /// <summary> 
     /// Initializes a new instance of the <see cref="FileAccessHelperException"/> class with serialized data. 
     /// </summary> 
     /// <param name="info"> 
     /// The System.Runtime.Serialization.SerializationInfo that holds the serialized 
     /// object data about the exception being thrown. 
     /// </param> 
     /// <param name="context"> 
     /// The System.Runtime.Serialization.StreamingContext that contains contextual 
     /// information about the source or destination. 
     /// </param> 
     /// <exception cref="System.ArgumentNullException"> 
     /// The info parameter is null. 
     /// </exception> 
     /// <exception cref="System.Runtime.Serialization.SerializationException"> 
     /// The class name is null or System.Exception.HResult is zero (0). 
     /// </exception> 
     [SecuritySafeCritical] 
     protected FileAccessHelperException(SerializationInfo info, StreamingContext context) 
      : base(info, context) 
     { 
     } 
    } 
} 

我希望帮助;-)

+0

啊......已经迟了... StreamReader应该已经打开流只读,所以第二个解决方案应该(希望)帮助。 –