我想通过我的macOS应用程序中的adb
命令从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
时,文件将被拉到我的计算机上。
这里的奇怪之处在于,如果我从Xcode控制台输出中复制子字符串/storage/emulated/0/Download/Böse
,则在删除Terminal.app
并将其替换之前,该命令在ö
中也不起作用从我的键盘输入中输入ö
。
我尝试用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
如何处理我提供的参数的以下内容:
在通过argv []将它们传递给任务之前,NSTask对象将参数中的路径和字符串都转换为适当的C样式字符串(使用fileSystemRepresentation)。参数中的字符串不会进行shell扩展,因此您无需执行特殊的引号,并且不会解析shell变量(例如$ PWD)。
似乎我不是唯一遇到此问题的人,并且我找到了解决方法: How to work around NSTask calling -[NSString fileSystemRepresentation] for arguments,但我无法使其与Swift一起使用。
答案 0 :(得分:0)
作为一种解决方法,我现在将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)
即使此操作目前仍有效,但它也不是一种令人满意的解决方案,因为它也不是很优雅,效率也不高,因此欢迎进行任何改进或更好的答案。