如何获取NSRunningApplication启动期间使用的参数列表,类似于我运行ps aux时看到的参数列表:

let workspace = NSWorkspace.shared
let applications = workspace.runningApplications

for application in applications {
    // how do I get arguments that were used during application launch?
}

推荐答案

"ps"工具使用sysctl()KERN_PROCARGS2来获取正在运行的进程的参数.以下是将代码从adv_cmds-153/ps/print.c转换为Swift的try .该文件还包含原始参数空间内存布局的文档,并解释如何在该内存中定位字符串参数.

func processArguments(pid: pid_t) -> [String]? {
    
    // Determine space for arguments:
    var name : [CInt] = [ CTL_KERN, KERN_PROCARGS2, pid ]
    var length: size_t = 0
    if sysctl(&name, CUnsignedInt(name.count), nil, &length, nil, 0) == -1 {
        return nil
    }
    
    // Get raw arguments:
    var buffer = [CChar](repeating: 0, count: length)
    if sysctl(&name, CUnsignedInt(name.count), &buffer, &length, nil, 0) == -1 {
        return nil
    }
    
    // There should be at least the space for the argument count:
    var argc : CInt = 0
    if length < MemoryLayout.size(ofValue: argc) {
        return nil
    }
    
    var argv: [String] = []
    
    buffer.withUnsafeBufferPointer { bp in
        
        // Get argc:
        memcpy(&argc, bp.baseAddress, MemoryLayout.size(ofValue: argc))
        var pos = MemoryLayout.size(ofValue: argc)
        
        // Skip the saved exec_path.
        while pos < bp.count && bp[pos] != 0 {
            pos += 1
        }
        if pos == bp.count {
            return
        }
        
        // Skip trailing '\0' characters.
        while pos < bp.count && bp[pos] == 0 {
            pos += 1
        }
        if pos == bp.count {
            return
        }
        
        // Iterate through the '\0'-terminated strings.
        for _ in 0..<argc {
            let start = bp.baseAddress! + pos
            while pos < bp.count && bp[pos] != 0 {
                pos += 1
            }
            if pos == bp.count {
                return
            }
            argv.append(String(cString: start))
            pos += 1
        }
    }
    
    return argv.count == argc ? argv : nil
}

只有一个简单的错误处理:如果出现任何错误,函数将返回nil.

对于NSRunningApplication的实例,您可以调用

processArguments(pid: application.processIdentifier)

Swift相关问答推荐

在列表项内的NavigationLink中的按钮无法正常工作

VisionOS发送通知

如何消除SwiftUI中SF符号的填充

NSApplication是否需要NSApplicationDelegate?

如何在DATE()中进行比较

如何增加 NSStatusBar 图像大小?

BLE 在 ESP32 和 Iphone 之间发送字符串

暂停我的 AR 会话并清除变量和锚点的功能

如何在 Swift 中做类型安全的索引?

ConfirmationDialog取消swiftui中的错误

为什么在Swift中每次调用Decimal类型的formatted()方法都会越来越慢?

如何为 Swift UI 视图定义 struct ?

您可以在运行时访问 Picker 元素并更改它们的 colored颜色 吗

Swift UI 不重绘 NSViewRepresentable 包装的文本字段

Xcode:方法参数的代码完成

`@available` 属性在 macOS 版本上被错误地限制

更新我的 pod 导致 GoogleDataTransport Umbrella 标头出现错误

使 struct 可散列?

使用 Swift 在 iOS 8 中为应用程序图标添加徽章

显示 UIAlertController 的简单 App Delegate 方法(在 Swift 中)