我试图用简单的代码调用应用程序,如
public void Run(string command)
{
Process proc = new Process();
proc.StartInfo.FileName = "acvTemp.exe";
proc.StartInfo.Arguments = command;
proc.Start();
proc.WaitForExit();
}
我正在启动的fileName进程实际上会生成一个新窗口。它正在推出一些命令,使其无法退出。我是
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命令提示符,因为使用/ launch打开一个新命令窗口并且/ 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 :(得分:0)
这是应用程序的问题吗?我能做的任何工作 在它周围?
我想说应用程序可能没有任何问题。很可能该文件根本没有被操作系统本身完全释放。
常见的解决方法是尝试在Try / Catch块中读取文件,并将其包含在延迟的while循环中,或者从Timer调用该代码。
答案 1 :(得分:0)
提出了文件锁定问题的一种解决方案here。然后,您可以提取感兴趣的过程的PID。
然后,如果日志文件保持打开状态,直到进程退出,那么就有“信号量”。
答案 2 :(得分: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)
{
}
}
}
我希望有所帮助; - )