UWP集成Cortana实现条件查询与交互响应的示例代码求助
Hey there! Let's walk through exactly how to implement that custom voice flow you're after—where Cortana triggers your app, asks for a choice between a/b, then reads a dynamic job title (not static XML content) based on the user's reply. Here's a step-by-step breakdown with code examples:
1. First, Set Up Your Voice Command Definition (VCD)
Start by creating a VoiceCommands.xml file to define the initial trigger phrase. We won't hardcode the a/b options here because we want dynamic handling later:
<?xml version="1.0" encoding="utf-8"?> <VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.2"> <CommandSet xml:lang="en-us" Name="JobCommands"> <CommandPrefix>Cortana</CommandPrefix> <Example>check the available jobs</Example> <Command Name="CheckAvailableJobs"> <Example>check the available jobs</Example> <ListenFor>check the available jobs</ListenFor> <Feedback>Looking up available jobs...</Feedback> <Navigate Target="MainPage" /> </Command> </CommandSet> </VoiceCommands>
Don't forget to reference this file in your Package.appxmanifest under the Extensions section (look for the VoiceCommand extension type).
2. Register the Voice Commands on App Launch
In your App.xaml.cs, add code to register the VCD when the app starts so Cortana recognizes your command:
protected override async void OnLaunched(LaunchActivatedEventArgs e) { // Your existing launch code here... try { var voiceService = VoiceCommandService.InstalledVoiceCommandServiceForPackage("JobCommands"); await voiceService.SetVoiceCommandDefinitionsFromFileAsync(new Uri("ms-appx:///VoiceCommands.xml")); } catch (Exception ex) { Debug.WriteLine($"Oops, failed to register voice commands: {ex.Message}"); } }
3. Trigger Cortana's Follow-Up Question
When the user says "Hey Cortana check the available jobs", your app will activate. Handle this activation to kick off the multi-turn conversation:
protected override async void OnActivated(IActivatedEventArgs args) { if (args is VoiceCommandActivatedEventArgs voiceArgs) { var commandResult = voiceArgs.Result; if (commandResult.RulePath[0] == "CheckAvailableJobs") { // Create a connection to Cortana's voice service var vcConnection = VoiceCommandServiceConnection.FromAppServiceTriggerDetails( args as AppServiceTriggerDetails); // Ask the user to choose a or b var prompt = new VoiceCommandUserMessage { DisplayMessage = "Which one, a or b?", SpokenMessage = "Which one, a or b?" }; var response = VoiceCommandResponse.CreateResponse(prompt); await vcConnection.RequestDisambiguationAsync(response); // Set up handler for user's choice (see next step) vcConnection.DisambiguationReceived += async (sender, e) => { var userChoice = e.SelectedItem; string jobTitle = string.Empty; // Replace this with your actual data fetch logic (API, local DB, etc.) if (userChoice.Equals("a", StringComparison.OrdinalIgnoreCase)) { jobTitle = "Senior .NET Software Engineer"; } else if (userChoice.Equals("b", StringComparison.OrdinalIgnoreCase)) { jobTitle = "Mobile UX Designer"; } // Tell Cortana to speak the dynamic job title var reply = new VoiceCommandUserMessage { DisplayMessage = $"The job title is {jobTitle}", SpokenMessage = $"The job title is {jobTitle}" }; var successResponse = VoiceCommandResponse.CreateResponse(reply); await vcConnection.ReportSuccessAsync(successResponse); }; } } }
Quick Tips to Avoid Headaches
- Double-check your
Package.appxmanifesthas theAppServiceandVoiceCommandcapabilities enabled—this is a common gotcha. - For real-world use, replace the hardcoded job titles with a call to your backend API or local data store to get live job data.
- Test with Cortana in English (US) first if you're using the example VCD, since language settings matter for voice recognition.
内容的提问来源于stack exchange,提问作者Isaack Hussein

