2

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();
}
  • Did you look at this? http://stackoverflow.com/questions/7764088/net-console-application-as-windows-service – Rick S Mar 04 '14 at 21:43
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Mar 04 '14 at 21:55
  • @RickS, I'd gone through those links before posting the question. Do you have any suggestions on using Topshelf with a console app so that the console app can then call the third party exe and pass on the PDF file name to it. Would that work? – Flintlock Wood Mar 04 '14 at 23:15
  • Is there any reason to wait for exit of the command line utility? if you watch the folder for coming pdf files then you can just run the tool and let it do its work. And either after some time or by notification from another watcher to process excel file. – mybrave Mar 05 '14 at 16:59

2 Answers2

3

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.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Would it help if I move all my code to a console application and use topshelf to run it as a windows service? Would I then be able to call the third party pdf-to-excel command line exe from the console app? After googling all day I've pretty much given up on the idea of calling the third party exe from the windows service. – Flintlock Wood Mar 04 '14 at 23:11
  • The issue, I strongly suspect, is that the code runs in session 0. Topshelf won't change that. Am I right in thinking that step 3 involves automating Excel? – David Heffernan Mar 04 '14 at 23:16
  • Not sure what exactly you're asking but here's the flow: 1. Client wpf app drops a pdf into a server "pdf" folder 2. windows service picks it up using filesystemwatcher, runs the third party tool which generates and drops the excel into an "excel" folder. 3. Windows service then picks up the Excel file using a second filesystemwatcher, reads the file using OleDbConnection into data tables. Data is processed and dumped into a third "xml" folder. 4. Client wpf watches for the xml file, cleans it up, and displays the results. – Flintlock Wood Mar 04 '14 at 23:32
  • Just finished trying Topshelf + Console App combination. No luck. This time the cursor just steps through the code but no Excel file is generated. :-( The good part is that the windows service reads manually dropped Excel files and returns the processed data in xml file format as expected so at least the second half of the task is working. – Flintlock Wood Mar 05 '14 at 00:58
  • When you debug you will be debugging the console app right? And there not be running as a service in session 0. – David Heffernan Mar 05 '14 at 06:25
0

I would put into the code proper exception handling and logging to e.g. 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]));
    }
}
mybrave
  • 1,662
  • 3
  • 20
  • 37
  • Under Log On tab, the Local System account is selected along with Allow service to interact with desktop. This I believe has high level of privileges. Unfortunately, the third party exe is all I have. No dlls. – Flintlock Wood Mar 04 '14 at 22:28
  • 1
    Thanks for the code. I already had pretty much exactly that but it didn't work. What I finally did was create a GUI-less windows application and ran it on the server with a task scheduler. I selected the option to run even without logged in users. I also had to create a folder (C:\Windows\SysWOW64\config\systemprofile\Desktop) because without this folder my application running through task scheduler was not creating the excel file (not sure how this folder fixed that problem). Anyway now the pdf2xl exe is running and creating the excel output. – Flintlock Wood Mar 06 '14 at 23:26