Unity中启动和关闭外部程序的完整指南
在Windows 平台使用 unity 打开其他程序。提供一些常见错误的解决方式。
目录
命名空间处理
using System.Diagnostics;
using Debug = UnityEngine.Debug; // 解决命名冲突
为什么要这样做?
当同时使用System.Diagnostics
和UnityEngine
命名空间时,Debug
类会产生歧义。通过别名定义明确指定使用Unity的调试工具。
路径
路径类型
类型 | 特点 | 使用场景 |
---|---|---|
绝对路径 | 包含完整盘符和目录结构 | 固定位置的外部程序 |
相对路径 | 基于项目目录的相对关系 | 可移植的附属程序 |
StreamingAssets操作
// 推荐使用Path.Combine自动处理路径分隔符
string appPath = Path.Combine(Application.streamingAssetsPath, "SubFolder", "MyApp.exe");
发布流程注意事项:
- 将外部程序放入
Assets/StreamingAssets
- 执行Unity构建
- 将程序重新拷贝到生成目录的
StreamingAssets
文件夹 - 保持目录结构一致性
程序启动
基础启动方式
// 绝对路径启动(适合固定位置程序)
Process.Start(@"D:\Program Files\MyApp\app.exe");
// 相对路径启动(推荐发布使用)
string relativePath = Path.Combine(Application.streamingAssetsPath, "MyApp.exe");
Process.Start(relativePath);
高级启动配置
ProcessStartInfo startInfo = new ProcessStartInfo() {
FileName = "cmd.exe",
Arguments = "/C echo Hello World",
WindowStyle = ProcessWindowStyle.Hidden
};
Process.Start(startInfo);
安全关闭进程
进程终止代码优化版
//终止程序,参数是程序名称(不带后缀)
void TerminateProcess(string processName) {
foreach (Process process in Process.GetProcesses()) {
try {
if (!process.HasExited &&
process.ProcessName.Equals(processName, StringComparison.OrdinalIgnoreCase)) {
process.Kill();
Debug.Log($"已终止进程: {processName}");
}
}
catch (Exception ex) {
Debug.LogError($"终止失败: {ex.Message}");
}
}
}
进程查询技巧
- 打开任务管理器 → 详细信息选项卡
- 右键表头启用"命令行"列
- 验证实际进程名称
常见问题解决方案
DLL加载失败问题
- 本地测试:先将程序放在桌面独立运行测试
- 路径检查:确保所有依赖文件完整
- 路径过长:
- 将程序移到更上层目录
- 重命名长文件夹名为缩写
文件未找到错误
- 使用
File.Exists()
进行预检查
if(File.Exists(appPath)){
Process.Start(appPath);
} else {
Debug.LogError($"程序不存在: {appPath}");
}
跨平台注意事项
路径处理差异
平台 | 路径特征 | 示例 |
---|---|---|
Windows | 反斜杠、盘符 | C:/AppData/Program/app.exe |
macOS | 正斜杠、无盘符 | /Applications/MyApp.app |
Linux | 正斜杠、区分大小写 | /usr/bin/myapp |
通用处理方案
// 自动适配平台路径
string GetUniversalPath(string[] pathParts) {
return Path.Combine(Application.streamingAssetsPath, Path.Combine(pathParts));
}
权限管理
// macOS/Linux需要添加执行权限
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
void AddExecutePermission(string path) {
ProcessStartInfo chmod = new ProcessStartInfo {
FileName = "chmod",
Arguments = $"+x \"{path}\"",
UseShellExecute = false
};
Process.Start(chmod)?.WaitForExit();
}
#endif