0

I have a service running as local SYSTEM that launches another application with the user credentials. That second app is only a tray icon that shows balloon tips to the user with the string received using the callback method. This second application connects to the WCF in duplex mode.

My problem is that for some reason the connection to the WCF is finalized at the end of the method Main. So I cannot send a callback message to the app right after the execution, included in the last line "kiosk.MyStart(args);". there the callback is still pointing to null.

Any idea how could I solve this issue?

static void Main(string []args)
{
    if (Environment.UserInteractive)
    {
         // Start the WCf service
         var host = new ServiceHost(typeof(WcfService));
         host.Open();

         //Launch the Kiosk Agent which connects to the WCF
         bool ret = ProcessAsUser.Launch("C:\\Program Files (x86)\\KIOSK\\KioskAgent.exe");
         WinService kiosk = new WinService(args);
         // some checks and a welcome message is sent to the user.
         kiosk.MyStart(args);

         //...
         //...
    }
}

Edit: to clarify a bit more, inside kiosk.MyStart method is where I try to execute the callback to show a welcome message, but the callback is still NULL. As a result I assume that the client was not properly started for any reason and I launch it once again...

            if (WcfService.Callback != null)
                WcfService.Callback.UIMessageOnCallback(UIMessage);
            else
                ProcessAsUser.Launch("C:\\Program Files (x86)\\KIOSK\\KioskAgent.exe");
YaKs
  • 143
  • 12
  • 1
    I don't understand what you're asking, nor where WCF is involved in that `kiosk.MyStart` method. What is the code you show? Is that the service? And where do get that something is null? And what is null then? `args` or `kiosk`? This really needs an [mcve]. – rene Dec 18 '17 at 16:37
  • It's a bad idea to rely on a Windows Service to successfully launch a GUI app. What if there is no user logged on? Perhaps consider Windows Task Manager with a _only run when logged on_ restriction? –  Dec 19 '17 at 05:17
  • @rene, the null I got it inside the Kiosk.mystart method when I try to call the callback. see the note that I added to the post. – YaKs Dec 19 '17 at 10:38
  • @MickyD you are right and that is why I also implemented a check if there is a user logon or not. if there is no user logged on, I dont try to find the tray icon process to send it any message. – YaKs Dec 19 '17 at 10:39
  • @jacortijo to start the client application you can also use the startup folder for all users `%programdata%\Microsoft\Windows\Start Menu\Programs\Startup` add a shortcut of kioskAgent to this folder [create-shortcut-on-desktop-c-sharp](https://stackoverflow.com/questions/4897655/create-shortcut-on-desktop-c-sharp) – live2 Dec 21 '17 at 06:41

1 Answers1

1

Add a try catch block over the callback method, if the client not reachable it falls in the catch you can unsubscribe it. Is also good practice send a keepalive message to your client, to check if it available.

private void InformClient(ClientInfo clientInfo)
{
    var subscribers = this._subscriberRepository.GetAll();
    foreach (var subscriber in subscribers)
    {
        try
        {
            if (subscriber.Callback.FireInformClient(clientInfo));
            {
                //If subscriber not reachable, unsubscribe it
                this._subscriberRepository.Unsubscribe(subscriber.ClientId);
            }
        }
        catch (Exception exception)
        {
            //If subscriber not reachable, unsubscribe it
            this._subscriberRepository.Unsubscribe(subscriber.ClientId);
            Log.Error(nameof(InformClient), exception);
        }
    }
}

IClientCallback

public interface IClientCallback
{
    [OperationContract]
    bool FireInformClient(ClientInfo clientInfo);
}

If you have more subscribers for example a terminal, server create a subscriberRepository to manage all subscribers.

var callback = OperationContext.Current.GetCallbackChannel<IClientCallback>();
if (this._subscriberRepository.Subscribe(clientId, callback))
{
    return true;
}
live2
  • 3,771
  • 2
  • 37
  • 46