You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于C# System Speech实现CSV文件夹别名语音打开的技术问询

解决方案:基于CSV配置的语音打开文件夹功能

核心思路

用**Dictionary<string, string>**存储CSV中的别名-路径映射,既方便读取配置,又能快速通过别名匹配对应路径,比数组索引匹配更高效。同时动态生成语音识别语法,彻底替代硬编码指令。

步骤实现

1. 读取CSV配置文件

读取CSV内容,将每行拆分为别名和路径,存入Dictionary:

// 假设CSV文件放在程序目录下的FolderAliases.csv
var aliasPathMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var line in File.ReadAllLines("FolderAliases.csv"))
{
    var parts = line.Split(',', StringSplitOptions.RemoveEmptyEntries);
    if (parts.Length == 2)
    {
        aliasPathMap[parts[0].Trim()] = parts[1].Trim();
    }
}

2. 动态构建语音识别语法

从Dictionary的键(别名)生成可选指令,构建「打开{别名}文件夹」的语法规则:

// 生成所有别名对应的选项
var aliasChoices = new Choices(aliasPathMap.Keys.ToArray());
// 组装语法模板
var grammarBuilder = new GrammarBuilder();
grammarBuilder.Append("打开");
grammarBuilder.Append(aliasChoices);
grammarBuilder.Append("文件夹");
// 加载语法到识别引擎
listener.LoadGrammarAsync(new Grammar(grammarBuilder));

3. 处理语音识别事件

识别到指令后,提取别名,从Dictionary中取路径并打开资源管理器:

private void Speech_recognize(object? sender, SpeechRecognizedEventArgs e)
{
    // 提取识别结果中的别名(语法模板的第2个元素)
    if (e.Result.Words.Count >= 2)
    {
        string alias = e.Result.Words[1].Text;
        if (aliasPathMap.TryGetValue(alias, out string? targetPath))
        {
            Process.Start(new ProcessStartInfo(targetPath) { UseShellExecute = true });
        }
    }
}

完整代码示例

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Speech.Recognition;
using System.Linq;

namespace WinFormsApp2
{
    public partial class Form1 : Form
    {
        private SpeechRecognitionEngine _listener = new SpeechRecognitionEngine();
        private Dictionary<string, string> _aliasPathMap = new(StringComparer.OrdinalIgnoreCase);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 读取CSV配置
            LoadFolderAliases();

            // 配置语音识别引擎
            _listener.SetInputToDefaultAudioDevice();
            _listener.SpeechRecognized += Speech_recognize;

            // 动态加载语法
            LoadRecognitionGrammar();
        }

        private void LoadFolderAliases()
        {
            string csvPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FolderAliases.csv");
            if (!File.Exists(csvPath))
            {
                // 可添加文件不存在的提示逻辑
                return;
            }

            foreach (var line in File.ReadAllLines(csvPath))
            {
                var parts = line.Split(',', StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length == 2)
                {
                    _aliasPathMap[parts[0].Trim()] = parts[1].Trim();
                }
            }
        }

        private void LoadRecognitionGrammar()
        {
            if (_aliasPathMap.Count == 0) return;

            var aliasChoices = new Choices(_aliasPathMap.Keys.ToArray());
            var grammarBuilder = new GrammarBuilder();
            grammarBuilder.Append("打开");
            grammarBuilder.Append(aliasChoices);
            grammarBuilder.Append("文件夹");

            _listener.LoadGrammarAsync(new Grammar(grammarBuilder));
        }

        private void Speech_recognize(object? sender, SpeechRecognizedEventArgs e)
        {
            if (e.Result.Words.Count >= 2)
            {
                string alias = e.Result.Words[1].Text;
                if (_aliasPathMap.TryGetValue(alias, out string? targetPath))
                {
                    try
                    {
                        Process.Start(new ProcessStartInfo(targetPath) { UseShellExecute = true });
                    }
                    catch (Exception ex)
                    {
                        // 可添加错误提示逻辑,比如路径不存在等
                        Debug.WriteLine($"打开失败: {ex.Message}");
                    }
                }
            }
        }

        private void listen_Click(object sender, EventArgs e)
        {
            _listener.RecognizeAsync(RecognizeMode.Multiple);
            listen.Enabled = false;
            stop.Enabled = true;
        }

        private void stop_Click(object sender, EventArgs e)
        {
            _listener.RecognizeAsyncCancel();
            listen.Enabled = true;
            stop.Enabled = false;
        }
    }
}

关键说明

  • Dictionary映射优势:相比数组,通过别名直接查找路径的时间复杂度为O(1),效率更高,无需维护索引对应关系。
  • 大小写兼容:StringComparer.OrdinalIgnoreCase确保语音识别的别名(如"temp"和"Temp")都能匹配到对应路径。
  • 动态更新:CSV文件修改后,重启程序即可加载新的别名指令,无需改动代码。

内容的提问来源于stack exchange,提问作者daftcranberry2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:03:49