简体   繁体   中英

Running a command line exe from windows service

I have a windows service that is intended to do the following:

  1. Monitor a folder on the server for PDF files
  2. When file arrives, run a third party exe to convert the PDF to Excel. No text output is generated. The third party tool simply uses the input file path and generates an output excel file. No need for a window launch. No need to track sessions.
  3. Windows service then reads the data from the Excel, processes it, and outputs an xml into a folder.

All this works fine in debug mode. However, when I try to run the windows service on my local machine in release mode (using installutil) as a service (as opposed to in visual studio), it does not work. When I attach-to-process, I notice the cursor just hangs on waitforexit and no excel is generated. Since it works in debug but not in release mode, I suspect it's a permissions issue. Any feedback will be appreciated.

Already tried checking "Allow service to interact with desktop". Didn't help.

EDIT: correction - cursor actually hangs on 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();
}

The problem is almost certainly that steps 2 and 3 do not work in the non-interactive session 0. The big difference is not between debug and release builds. But between running on the interactive desktop, and the service running in session 0.

To get out of this, and continue using a service, you need to make sure that all steps can operate in session 0. Step 2 we know nothing about. Step 3 looks like it involves automating Excel. That is officially not supported and known not to work under session 0. You'll need to read the Excel file using something other than Excel. As for step 2, that depends on the third party tool that converts from PDF to Excel.

I would put into the code proper exception handling and logging to eg event log to find out if there is anything different than expected.

Next step may be to configure the service with credentials which you know will have access to executable you try to run, to the directories where you export the files generated etc.

If possible / available then try to use assembly which you can reference instead of running another executable from your code. This way you will have it more under control;)

EDIT: In general it is possible to run command line tool by windows service. There just need to be clear how the tool expects to get the data, if it is from command line and tool is not waiting for user to enter anything. Do you have problem just with this command line utility or in general?

Service:

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());
    }
}

Command line tool - expects to get name of the file as parameter

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]));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM