4

I have a service that calls a process to create a file (the process is a winform), In my service, I want to read the file once the process creates the file, how can I communicate between my service and the process to check that the file has been created correctlly.

Process.Start(assemblyPath, xsdFileName + " " + fileName + " " + exportPDFFileName);
//here I need to make sure that the file has been created correctly
return new MemoryStream(File.ReadAllBytes(exportPDFFileName));

Thank you for your help, Bilel

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Bilel Chaouadi
  • 903
  • 1
  • 10
  • 28
  • Could you have the service periodically check if the file exists? – Patrick Mar 26 '19 at 11:39
  • 3
    Parallel processing has nothing to do with interprocess communication. Coordinating file access isn't a communication method either. – Panagiotis Kanavos Mar 26 '19 at 11:39
  • I think that this is not good for perfomances, I need something to transmit to my service once the file has been created. – Bilel Chaouadi Mar 26 '19 at 11:41
  • For interprocess communication, you could consider [Named Pipes](https://learn.microsoft.com/en-us/windows/desktop/ipc/named-pipes), but it's not cross-platform as far as I'm aware. – Patrick Mar 26 '19 at 11:42
  • 1
    @BilelChaouadi there are a *lot* of IPC methods. The parent process could read the output stream of the current process. You could use named pipes. TCP listeners. Sockets. SOAP services. Named mutexes. – Panagiotis Kanavos Mar 26 '19 at 11:43
  • Hi. You might be inspired by this library : https://github.com/TheCodeKing/XDMessaging.Net – Larry Mar 26 '19 at 11:44
  • When you say 'service' are you meaning Windows Service? If so then the service doesn't invoke a WinForms app. You can inject into a service, if it's designed that way. If the WinForms is asking the Service to write the file that makes a little more sense. Also, what you're doing is starting a process, which shouldn't be controlled or monitored from your current process the way you are intending to use it. There's a logic flaw here... Can you state step by step what you're wanting to achieve here and you might get the correct logic and answer? Otherwise, maybe it's not a service... – Michael Puckett II Mar 26 '19 at 11:45
  • No it is not a windows service, it is just a class library project – Bilel Chaouadi Mar 26 '19 at 11:51
  • @Panagiotis Kanavos could you please explain me how can I achieve this using TCP ? – Bilel Chaouadi Mar 26 '19 at 11:52

3 Answers3

1

A simple solution is using process.WaitForExit() to know when the process ended:

Process.Start(assemblyPath, xsdFileName + " " + fileName + " " + exportPDFFileName);
process.WaitForExit();
return new MemoryStream(File.ReadAllBytes(exportPDFFileName));

Note this will work only if you know for sure that the process actually creates the file. Otherwise, I suggest either looping with a sleep to make sure the file was created (using File.Exists(path)), or reading the process output to make sure it created the file. Read this post for this option.

Koby Douek
  • 16,156
  • 19
  • 74
  • 103
1

As already mentioned, use WaitForExit or HasExited - perhaps also investigating the process ExitCode. You could define values for ExitCode and this way signal if the file has been created etc. See this link for details.

But if you want to actually do some communication between your processes then consider using anonymous pipes.

Werner
  • 1,229
  • 1
  • 10
  • 24
0

If you're looking for inter-process communication protocol to describe a "wait for an action completion" semantic, it can be implemented with named event and named mutex synchronization primitives. The simplest mechanism of using these primitives is when some process in your case parent process creates a named synchronization object and waits for the signaled state of the object:

var fileCreationEvent = new EventWaitHandle(false, EventResetMode.ManualReset, "MyGloballyVisibleEvent");
...
fileCreationEvent.WaitOne();
// read your file

and another process, child process in your case, gets an access to existing event and sets it to the signaled state once it completes the some expected action:

var fileCreationEvent = EventWaitHandle.OpenExisting("MyGloballyVisibleEvent");
...
// create file here
fileCreationEvent.Set();

This is a simplified flow which doesn't take into account some concurrency aspects such as possibility that there are multiple processes which can create/delete the target file. If these things are important the approach is pretty similar to an approach you'd apply locally inside single process. In that case a file is kind of shared state which should be protected against the race conditions and you can use named Mutex for that in the same way as named event.

Dmytro Mukalov
  • 1,949
  • 1
  • 9
  • 14