【发布时间】:2021-03-17 10:56:22
【问题描述】:
所以我用 C# 编写了一个程序来获取当前可用的音频输出设备。因此,当我运行该过程时,我会在 DataReceived 事件中获得设备的名称。当它收到“DONE”时,它会终止进程并将保存的名称添加到 TMP_Dropdown 选项中。但问题是,当它到达 dropdown.ClearOptions() 时,程序只是停止而没有任何错误消息。当我添加断点并继续单步执行该功能时,黄色条就会消失,并且该功能会停止。但是当我只是向设备添加一些随机字符串而不运行 GetDevices() 时,它就像一个魅力。
这是我上面引用的代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using TMPro;
public class GetAudioOutputDevices : MonoBehaviour
{
private Process process = null;
public List<string> devices = new List<string>();
[SerializeField]
private TMP_Dropdown dropdown;
private string selected;
private void Start()
{
GetDevices();
}
//start new process that gets returns the current audio devices
private void GetDevices()
{
devices.Clear();
try
{
process = new Process();
process.EnableRaisingEvents = false;
process.StartInfo.FileName = Application.streamingAssetsPath + "/GetAudioDevices/GetAllAudioDevices.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = false;
process.OutputDataReceived += new DataReceivedEventHandler(DataReceived);
process.Start();
process.BeginOutputReadLine();
UnityEngine.Debug.Log("successfully started app");
}
catch (Exception e)
{
UnityEngine.Debug.LogError("unable to launch app:" + e.Message);
}
}
//event that recieves the data from the process
void DataReceived(object sender, DataReceivedEventArgs eventArgs)
{
// check if process is done
if (eventArgs.Data == "DONE")
{
process.Kill();
DoneReadingDevices();
}
else
{
if (!string.IsNullOrEmpty(eventArgs.Data))
{
if (eventArgs.Data.Contains("SELECTED:"))
{
string dat = eventArgs.Data;
dat = dat.Replace("SELECTED:", "");
selected = dat;
}
else
{
UnityEngine.Debug.Log(eventArgs.Data);
devices.Add(eventArgs.Data);
}
}
}
}
//adds the devices to a textmesh pro dropdown and selects the one that was passed as selected by the process
public void DoneReadingDevices()
{
dropdown.ClearOptions();
TMP_Dropdown.OptionData selectedOpDat = null;
dropdown.AddOptions(devices);
UnityEngine.Debug.Log(dropdown.options.Count);
foreach (TMP_Dropdown.OptionData d in dropdown.options)
{
if(d.text == selected)
{
selectedOpDat = d;
break;
}
}
if(selectedOpDat != null)
{
dropdown.value = dropdown.options.IndexOf(selectedOpDat);
}
else
{
UnityEngine.Debug.Log("didn't find matching data");
}
}
}
这是我编写的用于获取音频设备的 c# 程序:
using System;
using NAudio.CoreAudioApi;
namespace GetAllAudioDevices
{
class Program
{
static void Main(string[] args)
{
var enumerator = new MMDeviceEnumerator();
MMDevice active = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console);
foreach (var endpoint in enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active))
{
Console.WriteLine(endpoint.FriendlyName);
}
Console.WriteLine("SELECTED:" + active.FriendlyName);
Console.WriteLine("DONE");
Console.ReadLine();
}
}
}
【问题讨论】: