从Windows服务运行命令行exe

时间:2014-03-04 21:36:32

标签: c# .net process windows-services processstartinfo

我有一个Windows服务,旨在执行以下操作:

  1. 在服务器上监控PDF文件的文件夹
  2. 当文件到达时,运行第三方exe将PDF转换为Excel。没有生成文本输出。第三方工具只使用输入文件路径并生成输出excel文件。无需窗口启动。无需跟踪会话。
  3. Windows服务然后从Excel读取数据,处理它,并将xml输出到文件夹中。
  4. 所有这些在调试模式下都能正常工作。但是,当我尝试在发布模式(使用installutil)作为服务(而不是在visual studio中)运行本地计算机上的Windows服务时,它不起作用。当我附加到进程时,我注意到光标只挂在waitforexit上,并且没有生成excel。由于它在调试但不在发布模式下工作,我怀疑这是一个权限问题。任何反馈将不胜感激。

    已经尝试检查“允许服务与桌面交互”。没有帮助。

    编辑:更正 - 光标实际上挂在exeProcess.WaitForExit()

    ProcessStartInfo sInfo = new ProcessStartInfo();
    sInfo.FileName = ConfigurationManager.AppSettings["FileName"];
    sInfo.Arguments = GetArguments();
    sInfo.UseShellExecute = false;
    sInfo.CreateNoWindow = true;
    sInfo.ErrorDialog = false;
    sInfo.WindowStyle = ProcessWindowStyle.Hidden;
    //sInfo.RedirectStandardError = true;  //didn't work
    //sInfo.RedirectStandardInput = true;  //didn't work
    //sInfo.RedirectStandardOutput = true;  //didn't work
    
    
    using (Process exeProcess = Process.Start(sInfo))
    {
        //StreamWriter inputWriter = exeProcess.StandardInput;
        //StreamReader outputReader = exeProcess.StandardOutput;
        //StreamReader errorReader = exeProcess.StandardError;
        exeProcess.WaitForExit();
    }
    

2 个答案:

答案 0 :(得分:3)

问题几乎可以肯定,步骤2和3在非交互式会话0中不起作用。调试版本和发布版本之间并不存在很大差异。但是在交互式桌面上运行和在会话0中运行的服务之间。

要摆脱这种情况,并继续使用服务,您需要确保所有步骤都可以在会话0中运行。步骤2我们一无所知。第3步看起来涉及自动化Excel。这是官方不支持的,并且已知不能在会话0下工作。您需要使用Excel之外的其他内容来读取Excel文件。至于第2步,这取决于从PDF转换为Excel的第三方工具。

答案 1 :(得分:0)

我会在代码中加入适当的异常处理并记录到例如事件日志,以确定是否有任何不同于预期的事件。

下一步可能是使用您知道可以访问您尝试运行的可执行文件的凭据来配置服务,以及导出生成的文件的目录等。

如果可能/可用,那么尝试使用您可以引用的程序集,而不是从代码中运行另一个可执行文件。这样你就可以控制它了;)

编辑: 通常,可以通过Windows服务运行命令行工具。只需要清楚工具如何获取数据,如果它来自命令行,工具不等待用户输入任何内容。您是否只使用此命令行实用程序或一般情况下遇到问题?

服务:

private FileSystemWatcher watcher;

public Service1()
{
    InitializeComponent();
}

protected override void OnStart(string[] args)
{
    watcher = new FileSystemWatcher();
    watcher.Path = @"c:\temp\service";
    watcher.Created += watcher_Created;
    watcher.EnableRaisingEvents = true;

}

protected override void OnStop()
{
}

private void watcher_Created(object sender, FileSystemEventArgs e)
{
    try
    {
        ProcessStartInfo startInfo = new ProcessStartInfo(pathToExe, e.Name);
        EventLog.WriteEntry(e.Name);

        Process process = Process.Start(startInfo);
        process.EnableRaisingEvents = true;
    }
    catch (Exception ex)
    {
        EventLog.WriteEntry(ex.ToString());
    }
}

命令行工具 - 期望将文件名称作为参数

public class Program
{
    public static void Main(string[] args)
    {
        File.AppendAllText(pathToLog, string.Format("{0} - File got created in watched folder - doing conversion of {1}\n", DateTime.Now, args[0]));
    }
}