发送语音识别参数。结果作为UWP桌面桥程序包中的参数

l80*_*l80 6 c# events parameter-passing uwp desktop-bridge

我试图弄清楚,是否有可能using Windows.Media.SpeechRecognition; args.Result.Text作为参数从UWP发送到控制台应用程序。

例如,通过遵循以下方案,我将发送TextToSpeech(args.Result.Text);具有args.Result.Text;价值的值,其中using Windows.Media.SpeechSynthesis;每次出现时,文本语音转换都会发出识别结果args.Result.Text;textBlock2.Text = args.Result.Text;还显示结果:

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

                TextToSpeech(args.Result.Text);               
            });
        }
Run Code Online (Sandbox Code Playgroud)

但如果我要发送args.Result.Text;作为参数传递给控制台应用程序,包括与UWP桌面桥包:

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

          SendTTSResult(args.Result.Text);
        });
    }
Run Code Online (Sandbox Code Playgroud)

到请求的功能:

 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");
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

在我看来,失败的行为并不十分清楚:

有了第一个识别结果,它将参数发送到控制台应用程序,控制台应用程序成功加载,获取并显示此参数。但是,有了第二个请求,问题就从该处理级别退后了,即使参数发送功能是明确的,SendTTSResult(args.Result.Text);也不会接收到故障功能的原因, args.Result.Text但这已经在功能生效之前发生,因为先前的输出显示 textBlock1.Text = args.Result.Text;也不再接收事件了。

随着async() =>行为是有点不同,它成功地接收事件,并将值作为参数传递给控制台,在这种情况下,它会发生2-3次,从执行和语音请求,然后消失的事件,当它甚至没有穿过开始SendTTSResult(string res),想象的内容SendTTSResult(string res)不允许从识别中传递字符串,而是停止,即使我将其放在TextToSpeech(string text)函数末尾,文本到语音也停止接收事件:

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");
                }
            });
        }
Run Code Online (Sandbox Code Playgroud)

看起来像发送args.Result.Text带有参数的参数一样,该SendTTSResult(string res)函数可以正常工作,可以成功发送字符串,但是与此同时,该函数的存在ContinuousRecognitionSession_ResultGenerated也会影响其内部事件的接收。同时ContSpeechRecognizer_HypothesisGenerated看起来的行为完全不同,args.Hypothesis.Text事件每次都出现并且结果成功地传递给具有相同参数的参数SendTTSResult(string res)

当在其过程中涉及发送参数的功能时,如何阻止事件执行?如何解决该问题?

在Windows Dev Center上我的问题中添加了连续语音识别的完整代码发送语音识别args.Result作为UWP桌面桥包中的参数

编辑1: *************************************************** ****************************************************** *

在参数功能的后面,控制台Connector.exe仅显示参数,而不运行任何应用程序或其他任何东西:

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;
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

编辑2: *************************************************** ****************************************************** *

我试过更SendTTSResult(SpeechRecogVal);改变量值:

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

但这是相同的行为,tbRec.Text = SpeechRecogVal;直到我添加成功为止SendTTSResult(SpeechRecogVal);, 显示输出成功

   private string _srVal;

    public string SpeechRecogVal
    {
        get
        {
            return _srVal;
        }

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

    void ValueChanged()
    {
        tbRec.Text = SpeechRecogVal;
        // SendTTSResult(SpeechRecogVal);
    }
Run Code Online (Sandbox Code Playgroud)

所以,似乎问题是介于await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>和如果(ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))与 之间await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>private async voidContinuousRecognitionSession_ResultGenerated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)

另外,我尝试了:

private async void ContinuousRecognitionSession_ResultGenerated(
    SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
       await  SendTTSResult(args.Result.Text);        
}
Run Code Online (Sandbox Code Playgroud)

作为任务:

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");
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

而且,只有在第一个请求事件实例响应成功后,它才能成功。因此似乎与Windows.Media.SpeechRecognition命名空间中的ContinuousRecognitionSession_ResultGenerated其他选项有所不同,并且与以下代码行内容中的某些内容不兼容 :async Task SendTTSResult(string res)

 ApplicationData.Current.LocalSettings.Values["parameters"] = args.Result.Text;
 await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
Run Code Online (Sandbox Code Playgroud)

Nic*_*SFT 1

System.NullReferenceException发生appservice断开连接的情况,您可以在发送消息之前检查apservice的连接吗?

为了解释这一点,我创建了参考Stefanwick 博客的示例项目。当我不在InitializeAppServiceConnectionWPF 客户端中调用方法时,我也会重现您的问题。如果您想将文本发送到 wpf,您可以调用Connection.SendMessageAsync方法,如下所示SendMesssageclick event 。

能力

      <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>
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

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;
         });

     }
 }
Run Code Online (Sandbox Code Playgroud)

这是完整的代码示例