5

I'm trying to figure out, if it is possible send using Windows.Media.SpeechRecognition; args.Result.Text as parameter from UWP to Console application.

For example by following scenario I'm sending TextToSpeech(args.Result.Text); with args.Result.Text; value, where using Windows.Media.SpeechSynthesis; text-to-speech pronounces the recognition result each time when args.Result.Text; appears. textBlock2.Text = args.Result.Text; also displays result:

 private async void ContinuousRecognitionSession_ResultGenerated(
            SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
        {
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {               
                textBlock1.Text = args.Result.Text;    

                TextToSpeech(args.Result.Text);               
            });
        }

but if I'm trying to send args.Result.Text; as parameter to console application, included with UWP in Desktop-Bridge package:

    private async void ContinuousRecognitionSession_ResultGenerated(
        SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
    {
        await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {                            
          textBlock1.Text = args.Result.Text; 

          SendTTSResult(args.Result.Text);
        });
    }

to the requested function:

 private async void SendTTSResult(string res)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
            {
                ApplicationData.Current.LocalSettings.Values["parameters"] = res;
                await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
            }
        });
    }

Behavior of failure looks to me not really clear:

With first recognition result, it sends parameter to console application, which successfully loads, gets and displays this parameter. But with second request the problem backs away from this processing level, even if parameters sending function is unambiguously the cause of a failure SendTTSResult(args.Result.Text); function does not receives args.Result.Text but this happens already before function will comes in action, because preceding output display textBlock1.Text = args.Result.Text; also does not receives event anymore.

With async() => behavior is a bit different, it successfully receives event and sends value as parameter to console, in this case it happens 2-3 times from beginning of execution and voice requesting, then event disappears, when it is not even passed through SendTTSResult(string res), to imagine that the something in SendTTSResult(string res) does not allows pass string from recognition, but just stops, even if I put it in the end of TextToSpeech(string text) function, text to speech also stops receive event:

private async void SendTTSResult(string res)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
            {
                if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
                {
                    ApplicationData.Current.LocalSettings.Values["parameters"] = res;
                    await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
                }
            });
        }

It looks like sending of args.Result.Text value as parameter with SendTTSResult(string res) function works fine, sends string successfully, but at the same time presence of this function in ContinuousRecognitionSession_ResultGenerated somehow affects receiving of event inside of it. At the same time behavior of ContSpeechRecognizer_HypothesisGenerated looks completely different, args.Hypothesis.Text event appears each time and result successfully passes as parameter with same SendTTSResult(string res).

What can prevent an event from being executed when the function of sending a parameter is involved in its process, and how to fix it if possible?

Full code of continuous speech recognition added to my question on Windows Dev Center Send speech recognition args.Result as parameter in UWP desktop-bridge package

EDIT 1: **************************************************************************************************

Behind parameter function, Console Connector.exe only shows parameter without running of any app or anything else:

static void Main(string[] args)
        {
            string result = Assembly.GetExecutingAssembly().Location;
            int index = result.LastIndexOf("\\");
            string rootPath = $"{result.Substring(0, index)}\\..\\";
            if (args.Length > 2)
            {
                switch (args[2])
                {
                    case "/parameters":
                        string parameters = ApplicationData.Current.LocalSettings.Values["parameters"] as string;
                        Console.WriteLine("Parameter: " + parameters);
                        Console.ReadLine();
                        break;
                }
            }
        }

Packeage.appxmanifest:

<uap:Extension Category="windows.appService">
  <uap:AppService Name="SampleInteropService" />
</uap:Extension>

<desktop:Extension Category="windows.fullTrustProcess" Executable="Connector\Connector.exe">
  <desktop:FullTrustProcess>
    <desktop:ParameterGroup GroupId="Parameters" Parameters="/parameters" />
  </desktop:FullTrustProcess>
</desktop:Extension>

EDIT 2: **************************************************************************************************

I've tried SendTTSResult(SpeechRecogVal); with change of variable value:

 private async void ContinuousRecognitionSession_ResultGenerated(
        SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
    {
        await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {               
            SpeechRecogVal = args.Result.Text;
        });
    }

but it is same behavior tbRec.Text = SpeechRecogVal; shows output successfully until I add SendTTSResult(SpeechRecogVal);,

   private string _srVal;

    public string SpeechRecogVal
    {
        get
        {
            return _srVal;
        }

        set
        {
            _srVal = value;
            ValueChanged();
        }
    }

    void ValueChanged()
    {
        tbRec.Text = SpeechRecogVal;
        // SendTTSResult(SpeechRecogVal);
    }

So, seems like problem is something between await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => and if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0)) and await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => of private async voidContinuousRecognitionSession_ResultGenerated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)

Also, I've tried:

private async void ContinuousRecognitionSession_ResultGenerated(
    SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
       await  SendTTSResult(args.Result.Text);        
}

as Task:

async Task SendTTSResult(string res)
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
            {
                ApplicationData.Current.LocalSettings.Values["parameters"] = res;
                await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
            }
        });
    }

And it is also successful only with first request event instance response, then goes quite. So seems like ContinuousRecognitionSession_ResultGenerated is someway different from other options in Windows.Media.SpeechRecognition Namespace and not compatible with something in async Task SendTTSResult(string res) or rather with this code lines content:

 ApplicationData.Current.LocalSettings.Values["parameters"] = args.Result.Text;
 await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
lf80
  • 455
  • 3
  • 10
  • 22
  • For your requirement, I suggest you communicate with Console app with appservice. For more info please refer this [topic](https://stefanwick.com/2018/04/16/uwp-with-desktop-extension-part-3/). – CoCaIceDew Jul 10 '19 at 13:41
  • @CoCaIceDew Hello, well, I've question on this here [System.NullReferenceException in AppServiceResponse and System.BadImageFormatException of UWP with WPF desktop bridge package](https://social.msdn.microsoft.com/Forums/windowsapps/en-US/55b79e1f-06f4-49c8-8e06-895c859fc4ce/systemnullreferenceexception-in-appserviceresponse-and-systembadimageformatexception-of-uwp-with?forum=wpdevelop), but particular task does not goes beyond package content, so, you're saying, that the `args.Result` cannot be passed as parameter to console? – lf80 Jul 10 '19 at 13:50
  • I can't find where you pass the `args.Result.Text` to console app. Could you point it out. – Nico Zhu Jul 10 '19 at 15:02
  • @Nico Zhu Hello, check my EDIT 1 please. Also you can check my question on Windows Dev Center: [Send speech recognition args.Result as parameter in UWP desktop-bridge package](https://social.msdn.microsoft.com/Forums/windowsapps/en-US/1af5f3d1-d5b2-4a0c-956c-53f550e8f1d1/send-speech-recognition-argsresult-as-parameter-in-uwp-desktopbridge-package?forum=wpdevelop) – lf80 Jul 10 '19 at 15:10
  • So, you just store the text to to the local storage and fetch the data in the console app, right? – Nico Zhu Jul 10 '19 at 15:16
  • @Nico Zhu - MSFT Yes, and it works fine with `ContSpeechRecognizer_HypothesisGenerated` `args.Hypothesis.Text` as well as not continuous Speech Recognition method `speechRecognitionResult.Text;`. So as fact, if event exist, function sends parameter successfully, but by some reason including of `SendTTSResult(string res)` someway prevents event, for example for previous `textBlock1.Text = args.Result.Text;` – lf80 Jul 10 '19 at 15:24
  • We often use local setting to store some configuration information.It is not good practice, and I could not reproduce your problem, – Nico Zhu Jul 10 '19 at 15:34
  • @Nico Zhu - MSFT So, you're saying that the `ContinuousRecognitionSession_ResultGenerated` fires event with `SendTTSResult(string res)` included and sends string as parameter every time you make a voice request? – lf80 Jul 10 '19 at 15:40
  • I mean that you could send the text with appservice when make a voice request every time. – Nico Zhu Jul 11 '19 at 11:10
  • @Nico Zhu - MSFT Fact is that the `args.Hypothesis.Text` fires event, sends as parameter with included `SendTTSResult(string res)` and receives to console successfully, as well as with non Continuous method. Anyway, I've fully described my appservice problem with project repository included in last comment, but still can't fix it: [System.NullReferenceException in AppServiceResponse](https://social.msdn.microsoft.com/Forums/windowsapps/en-US/55b79e1f-06f4-49c8-8e06-895c859fc4ce/systemnullreferenceexception-in-appserviceresponse-and-systembadimageformatexception-of-uwp-with?forum=wpdevelop) – lf80 Jul 11 '19 at 13:34
  • Ok, I will check the `System.NullReferenceException in AppServiceResponse` issue – Nico Zhu Jul 11 '19 at 14:15
  • @Nico Zhu - MSFT Thank you! And please, also check my EDIT 2, which is another attempt result in particular task – lf80 Jul 11 '19 at 16:37
  • `System.NullReferenceException` occurs appservice disconnect scenario, Could you check the apservice's connection before send message? – Nico Zhu Jul 12 '19 at 08:17

1 Answers1

1

System.NullReferenceException occurs appservice disconnect scenario, Could you check the apservice's connection before send message?

For explain this, I create sample project that refer Stefanwick blog. And I also reproduce your issue when I does not invoke InitializeAppServiceConnection method in WPF client. If you want to send text to wpf, you could invoke Connection.SendMessageAsync method just like below SendMesssage click envent .

Capability

      <Extensions>
        <uap:Extension Category="windows.appService">
          <uap:AppService Name="SampleInteropService" />
        </uap:Extension>
        <desktop:Extension Category="windows.fullTrustProcess" Executable="AlertWindow\AlertWindow.exe" />
      </Extensions>
    </Application>
  </Applications>
  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="runFullTrust" />
  </Capabilities>

WPF

private AppServiceConnection connection = null;
public MainWindow()
{
    InitializeComponent();
    InitializeAppServiceConnection();
}
private async void InitializeAppServiceConnection()
{
    connection = new AppServiceConnection();
    connection.AppServiceName = "SampleInteropService";
    connection.PackageFamilyName = Package.Current.Id.FamilyName;
    connection.RequestReceived += Connection_RequestReceived;
    connection.ServiceClosed += Connection_ServiceClosed;

    AppServiceConnectionStatus status = await connection.OpenAsync();
    if (status != AppServiceConnectionStatus.Success)
    {
        MessageBox.Show(status.ToString());
        this.IsEnabled = false;
    }
}

private void Connection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
{
    Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
    {
        Application.Current.Shutdown();
    }));
}

private async void Connection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
    // retrive the reg key name from the ValueSet in the request
    string key = args.Request.Message["KEY"] as string;

    if (key.Length > 0)
    {
        Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
        {
            InfoBlock.Text = key;

        }));
        ValueSet response = new ValueSet();
        response.Add("OK", "SEND SUCCESS");
        await args.Request.SendResponseAsync(response);
    }
    else
    {
        ValueSet response = new ValueSet();
        response.Add("ERROR", "INVALID REQUEST");
        await args.Request.SendResponseAsync(response);
    }
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
    ValueSet response = new ValueSet();
    response.Add("OK", "AlerWindow Message");
    await connection.SendMessageAsync(response);
}

UWP

 protected async override void OnNavigatedTo(NavigationEventArgs e)
 {
     base.OnNavigatedTo(e);

     if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
     {
         App.AppServiceConnected += MainPage_AppServiceConnected;
         App.AppServiceDisconnected += MainPage_AppServiceDisconnected;
         await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
     }
 }

 private async void MainPage_AppServiceDisconnected(object sender, EventArgs e)
 {
     await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
     {
         Reconnect();
     });
 }



private void MainPage_AppServiceConnected(object sender, AppServiceTriggerDetails e)
 {
     App.Connection.RequestReceived += AppServiceConnection_RequestReceived;

 }
 private async void AppServiceConnection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
 {
     string value = args.Request.Message["OK"] as string;
     await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
      {
          InfoBlock.Text = value;
      });


 }     
 private async void Reconnect()
 {
     if (App.IsForeground)
     {
         MessageDialog dlg = new MessageDialog("Connection to desktop process lost. Reconnect?");
         UICommand yesCommand = new UICommand("Yes", async (r) =>
         {
             await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
         });
         dlg.Commands.Add(yesCommand);
         UICommand noCommand = new UICommand("No", (r) => { });
         dlg.Commands.Add(noCommand);
         await dlg.ShowAsync();
     }
 }
 private int count = 0;
 private async void SendMesssage(object sender, RoutedEventArgs e)
 {
     count++;
     ValueSet request = new ValueSet();
     request.Add("KEY", $"Test{count}");
     AppServiceResponse response = await App.Connection.SendMessageAsync(request);

     // display the response key/value pairs

     foreach (string value in response.Message.Values)
     {
         await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
         {
             StatusBlock.Text = value;
         });

     }
 }

This is complete code sample.

Nico Zhu
  • 32,367
  • 2
  • 15
  • 36
  • Hello, would be correct post this answer on my another topic on this task: [System.BadImageFormatException in UWP](https://stackoverflow.com/questions/56926852/system-badimageformatexception-in-uwp-with-wpf-desktop-bridge-package) also supported on WDC: [System.BadImage](https://social.msdn.microsoft.com/Forums/windowsapps/en-US/55b79e1f-06f4-49c8-8e06-895c859fc4ce/systemnullreferenceexception-in-appserviceresponse-and-systembadimageformatexception-of-uwp-with?forum=wpdevelop) – lf80 Jul 12 '19 at 15:30
  • This question not fully provoked by BadImage problem with creating of app connection in Package, but to Speech recognition event and parameters function interaction. I also imagine a different way, if I will receive parameter from CSR to console. So, I will put edit with results to your answer, please check **EDIT 5** here: [System.BadImageFormatException](https://stackoverflow.com/questions/56926852/system-badimageformatexception-in-uwp-with-wpf-desktop-bridge-package) – lf80 Jul 12 '19 at 15:31
  • To look at problem, described in particular question, please, check my last comment on this topic [Send speech recognition args.Result](https://social.msdn.microsoft.com/Forums/windowsapps/en-US/1af5f3d1-d5b2-4a0c-956c-53f550e8f1d1/send-speech-recognition-argsresult-as-parameter-in-uwp-desktopbridge-package?forum=wpdevelop), which includes details and easy guide to build this [UWP_SR_desktop_bridge](https://github.com/ladooniani/UWP_SR_desktop_bridge) demo – lf80 Jul 12 '19 at 15:39
  • So, I've have alternative idea of implementation, if I will get event result to console successfully, based on my main goal: [UWP Windows.Media.SpeechSynthesis events](https://social.msdn.microsoft.com/Forums/windowsapps/en-US/09fec565-ed4e-4b5d-be6d-bbc0c748dbe7/uwp-windowsmediaspeechsynthesis-viseme-speakprogress-speakcompleted-event-using?forum=wpdevelop) That's why would be correct and clear, keep this particular question on its own track – lf80 Jul 12 '19 at 15:45
  • It is same `System.NullReferenceException` and `System.BadImageFormatException` please check [EDIT 5](https://stackoverflow.com/questions/56926852/system-badimageformatexception-in-uwp-with-wpf-desktop-bridge-package) – lf80 Jul 12 '19 at 15:49