0

我正在 node.js 中构建一个小应用程序,用于execa读取来自已编译 Swift 应用程序的打印语句。这个想法类似于 Sindre Sorhus(还有谁!?)请勿打扰

虽然我不是 Swift 程序员,但我提出了一个非常简单的解决方案。swift build --configuration=release二进制文件通过从 CL运行编译以在节点应用程序中使用。它还在 XCode 的 Swift 操场上编译得很好(没有 CLI 部分),我可以看到正确的打印语句进入。

import Cocoa

var isLocked:Bool = false

DistributedNotificationCenter.default().addObserver(forName: .init("com.apple.isScreenLocked"), object: nil, queue: nil) { notification in
    print("Screen is locked")
    isLocked = true
}

DistributedNotificationCenter.default().addObserver(forName: .init("com.apple.isScreenUnlocked"), object: nil, queue: nil) { notification in
    print("Screen is unlocked")
    isLocked = false
}

struct CLI {
    static var standardInput = FileHandle.standardInput
    static var standardOutput = FileHandle.standardOutput
    static var standardError = FileHandle.standardError
    static let arguments = Array(CommandLine.arguments.dropFirst(1))
}

switch CLI.arguments.first {
case "status":
    print(isLocked)
default:
    print("Unsupported command", to: .standardError)
    exit(1)
}

// Some other functions omitted for brevity

现在,当我从 Node.js 运行以下代码时,一切似乎都运行良好。但是由于某种原因,观察者没有收到通知。

'use strict';
const execa = require('execa');
const electronUtil = require('electron-util/node');

const binary = path.join(electronUtil.fixPathForAsarUnpack(__dirname), 'IsLockedOrNot');

setInterval(async () => {
    const {stdout} = await execa(binary, ['status']);
    console.log(stdout) // keeps logging false, also when screen is locked
}, 1000)

有谁知道为什么在这种情况下没有收到通知?我尝试了各种方法,例如明确禁用睡眠模式并使用标志shell.exec('sudo pmset -a disablesleep 1')编译应用程序。--disable-sandbox然而,在知道之前没有运气。

4

1 回答 1

0

使用来自基本 child_process 库而不是 execa 的 spawn,确保您遵循标准输出,对于 nodejs 和 swift 最重要的部分是在每一行之后刷新缓冲区。否则,您必须等待程序终止,然后才能收到任何输出。在每次需要“换行符”的“打印”之后使用“import Darwin.C”和“fflush(stdout)”

于 2021-03-03T06:20:40.797 回答