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)
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)
这是完整的代码示例。
| 归档时间: |
|
| 查看次数: |
223 次 |
| 最近记录: |