2013-10-25 2 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> 

Примечание фактическое возвращение/процесс запуска в оболочке командной строки, так как с/запустить новое окно командной строки открывается и выход/GetId фактически записывается в журнал.

Моя проблема в том, когда запускаются команды first/launch или/getid, waitforexit(), похоже, выходит даже до того, как дескриптор выпущен в журнале. (может быть, до того, как некоторые дети вышли из строя?)

I.e: Следующая команда не работает, пока я не посплю или не подожду между ними. даже с 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() здесь, потому что запущена новая оболочка.

[обновление]

Проблема не только с файлом журнала. Когда я запускаю Run («/ getid:»), скажем, около 100 000 имен файлов, многие из них терпят неудачу с ошибкой «ресурсы недоступны», поэтому я думал, что приложение может выйти даже до выпуска своих ресурсов. Thanks для поиска.

+0

Делайте это в цикле, ожидания между попытками. – Dialecticus

+0

Я добавил обновление в конце вопроса. Благодарю. – user393148

ответ

0

Это проблема с приложением? Что-нибудь, что я могу сделать, чтобы работать вокруг него?

Я бы сказал, что, вероятно, нет проблем с приложением. Скорее всего, файл просто не был полностью выпущен самой операционной системой.

Общей задачей является обернуть попытку прочитать файл в блоке Try/Catch и либо заключить, что в цикле while с задержкой, либо вызвать этот код из таймера.

+0

Спасибо за ваш ответ. Проблема заключается не только в файле журнала. Когда я запускаю Run («/ getid: »), скажем, около 100 000 имен файлов, многие из них терпят неудачу с ошибкой «ресурсы недоступны», поэтому я думал, что приложение может выйти даже до его освобождения своих ресурсов – user393148

+0

Вставляет ли ожидание между каждой командой Run() решение? – user393148

+0

Ха-ха ... это какая-то важная информация, которую вы оставили там! Трудно сказать, какая сумма задержки необходима для того, чтобы это приложение работало «правильно». Кто знает, как он кодируется внутри страны. Кроме того, что делать, если условия всей системы меняются, а затем задержка, которая срабатывала раньше, больше не работает? Я думаю, что лучшее, что вы собираетесь получить, это просто настроить задержку в Sleep() между ними, а затем «молиться», чтобы она работала все время. Сожалею. –

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

Ah ... Уже поздно ... StreamReader должен уже открыть поток как прочитанный, так что второе решение должно (надеюсь) помочь. –

Смежные вопросы