android - 来自 macOS 应用程序的带有特殊字符的 ADB 命令
问题描述
我想通过adb
我的 macOS 应用程序中的命令从我的 android 设备中提取文件。
一切都与下面的代码完美配合,除非我要提取的文件名包含特殊字符,如德语变音符号 (äöüÄÖÜ)。
我得到这个错误:
adb: error: failed to stat remote object '/storage/emulated/0/Download/Böse': No such file or directory
。
但是,当我使用 中的命令时adb pull /storage/emulated/0/Download/Böse ~/Desktop
,Terminal.app
该文件将被拉到我的计算机上。
这里奇怪的是,如果我/storage/emulated/0/Download/Böse
从 Xcode 控制台输出中复制子字符串,则该命令也无法在其中工作,Terminal.app
直到我删除并用键盘输入ö
中的 an 替换它。ö
我尝试用ö
unicode 表示替换\u{00f6}
,但这没有效果(但控制台输出仍然显示一个ö
但“错误”编码的。
// Configure task.
let task = Process()
task.launchPath = "~/Library/Android/sdk/platform-tools/adb"
task.arguments = ["pull", "/storage/emulated/0/Download/Böse", "~/Desktop"]
// Configure pipe.
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.launch()
// Run task.
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()
// adb: error: failed to stat remote object '/storage/emulated/0/Download/Böse': No such file or directory
print(output)
我在文档中找到了以下内容,如何Process
处理我提供的参数:
NSTask 对象在通过 argv[] 将它们传递给任务之前,将路径和参数中的字符串转换为适当的 C 样式字符串(使用 fileSystemRepresentation)。参数中的字符串不进行 shell 扩展,因此不需要进行特殊引用,并且不解析 $PWD 等 shell 变量。
似乎我不是唯一一个遇到这个问题的人,我发现了这个解决方法: How to work around NSTask calling -[NSString fileSystemRepresentation] for arguments,但我无法让它与 Swift 一起工作。
解决方案
作为一种解决方法,我现在正在将我的 adb 命令写入文件并从我的应用程序中的 bash 命令执行它。
let source = "/storage/emulated/0/Download/Böse"
let destination = "~/Desktop"
guard let uniqueURL = URL(string: destination + "/" + ProcessInfo.processInfo.globallyUniqueString) else { return }
// Write command to file
let scriptContent = "#!/bin/bash\n~/Library/Android/sdk/platform-tools/adb pull -a \"" + source + "\" \"" + destination + "\""
try? scriptContent.write(to: uniqueURL, atomically: false, encoding: .utf8)
// Configure task.
let task = Process()
task.environment = ["LC_ALL": "de_DE.UTF-8", "LANG": "de_DE.UTF-8"]
task.launchPath = "/bin/bash"
task.arguments = [uniqueURL.path]
// Configure pipe.
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
try? task.run()
// Run task.
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()
print(output)
尽管这目前有效,但它不是一个令人满意的解决方案,因为它不是很优雅且效率也不高,因此欢迎任何改进或更好的答案。
推荐阅读
- reactjs - 带有参数的 Reactjs 书签 url
- html - 我对 flexbox 和响应式界面有疑问
- python - JSON文件未保存到Heroku Worker
- javascript - google.com 上的 JS 注入不起作用(chrome 扩展)
- c# - 以编程方式获取所有内置类型的列表
- authentication - SAPUI5 混合应用 - 如何防止在不同平台上多次登录
- swift - 为什么我不能将所有核心数据获取结果放入 UILabel?
- codeigniter - 如何从视图页面调用控制器方法?
- matlab - 使用 Simulink / Simscape 模拟感应电机
- javascript - 替换图像时如何使用 AJAX 刷新 DIV?