So you are basically trying to safely stop the SMP client while it is running as a service? The Tracker doesn't use service mode for any of the clients, so I wouldn't be able to help in that case.
However, if you are simply running the client with "hidden" window style then I know how to do that.(Basically if you are starting the client in such a way that it doesn't create a visible window but the client itself IS NOT starting as a service then this applies. Note that if the process is started from within another service then this will still work.)
I struggled with this same problem when I designed the Tracker. At first I had 2 options to stop the client:
1. Process.CloseMainWindow() - this method works great and safely closes the client, but it requires a visible window
2. Process.Kill() - this method works even when the process has no window, but it doesn't safely close it (WU may be lost)
Eventually I came up with the idea to create a small console application that served as a container for the FAH client. This container would wait for "exit" to be written to it's input stream then crtl+c itself (and the FAH client within it) This resulted in a safe exit for the client without it ever being visible. The downside to this method was complexity and memory usage (extra 4MB per client running) This is how some of the older versions of the Tracker worked.
Eventually I found a better way to close the clients. This method uses the sigsend.dll file that my friend made. It works by creating a new thread on the target process which then executes ctrl+c. This safely closes the client without the complexity associated with the container program or a visible window.
This is the VB declaration and a sample of its usage in the Tracker:
'this line goes in the declarations section
Private Declare Function SendSignal Lib "sigsend" (ByVal ProcessID As Integer) As Integer
'these lines would be used when you want to safely close a FAH client
Dim Result As Integer
Result = SendSignal(ProcessID)
'if the return value isn't 0 then something didn't work correctly so log an error (or w/e you want to do)
If Not Result = 0 Then
Log("Error")
End
The ProcessID input to SendSignal is the process ID that you want to close, and the return value is a success/fail indicator. I don't know all the return values that it gives but the common ones are:
0 = success
5 = process not found
Anyhow, feel free to use sigsend.dll for any project you want. SendSignal is the only function it contains. Hopefully this answers your question. If not you can always post the code you are using and I will see if I can find the problem.