V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
milkleeeeee
V2EX  ›  程序员

Node.js 可以通过 Native module 方便的调用操作系统的 API 吗?

  •  
  •   milkleeeeee · 51 天前 · 1301 次点击
    这是一个创建于 51 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我基本只懂前端开发相关的技术,最近在用 Electron 开发软件,然后需要一些操作系统层面的功能,比如:

    Node.js 支持用 C/C++ 开发 native module,但是,我在 GitHub 上几乎搜不到能调用这些操作系统 API 的 native module (目前找到的只有 NodeRT,但似乎只支持 Windows 10 且很久没有维护了),所以我想问:

    • 技术上是否能开发出一个能同时调用 macOS / Windows 上的这俩操作系统 API ,且能跨操作系统版本?(例如,同时支持 Window 10 / 11 、macOS 11 / 12 )
    • 如果能的话,难度大概多大,比如需要懂哪些技术、大概需要多长时间开发完成之类的?
    15 条回复    2022-05-06 17:30:50 +08:00
    f64by
        1
    f64by  
       51 天前
    可以,使用 node-gyp ,在 C++里编写逻辑,然后暴露 API 给 Node 调用
    statumer
        2
    statumer  
       51 天前
    从 electron 的角度讲,不一定需要让 js 直接调用 Objective-C ,而是可以通过进程间 IPC 的方式 (比如 socket, stdout ) 让 js 间接调用系统 API (参考 Clash, Chrome Native Messaging 的设计)。这种方法比起开发 node native addon 要简单很多。
    learningman
        3
    learningman  
       51 天前
    这两功能与其依赖不确定的操作系统实现,不如调云端接口算了
    ysc3839
        4
    ysc3839  
       51 天前 via Android

    难度很难量化,大概要懂 C++以及目标操作系统 API 的基本用法
    ysc3839
        5
    ysc3839  
       51 天前 via Android
    不过你这需求比较尴尬的地方是,上述两个 Windows API 都没有 DualApiPartitionAttribute ,很可能不能被 Win32 应用调用。
    OCR 我印象中是可以的,语音识别就未知了。
    magicdawn
        6
    magicdawn  
       51 天前
    调用 macOS NSPasteboard API 的例子 https://github.com/magicdawn/simple-mac-clipboard
    还是 NSPasteboard, 但是用的是 napi-rs https://github.com/magicdawn/clip-spy

    napi-rs 体验不错, 可以试试
    MEIyiyi
        7
    MEIyiyi  
       50 天前
    node 写 c++模块的场景多吗?( op 的问题我不懂,我就问问)
    agdhole
        8
    agdhole  
       50 天前
    react native windows?
    MasterMonkey
        9
    MasterMonkey  
       50 天前 via iPhone
    ysc3839
        10
    ysc3839  
       50 天前 via Android
    @MEIyiyi 看需求的,一般是需要使用系统功能,且 Node.js 本身没提供的时候用到
    liuzhedash
        11
    liuzhedash  
       50 天前
    @MasterMonkey
    node-ffi-napi 是可以的,前两年用这个调用过设备厂商提供的 win32 dll ,如果没 C/C++基础也没搞过 Windows 编程就比较棘手了。
    macos 没搞过不情路,猜测 node-ffi-napi 也可以加载 dylib/so ,和 win32 的 dll 差不多。
    milkleeeeee
        12
    milkleeeeee  
    OP
       50 天前
    @statumer #2 感谢,这也是个方法

    @ysc3839 #5 Win32 是指 32 位的操作系统没法调用这俩接口?不过对于我的需求而言,不支持 Win32 也没有关系

    @MasterMonkey #9 虽然文档上说不用写 C/C++ 就能调,但是看了下教程……完全整不明白,好像还是需要有 C/C++ 的技术背景才知道怎么用?
    ysc3839
        13
    ysc3839  
       50 天前 via Android   ❤️ 1
    @milkleeeeee Win32 大概可以理解为一套 API ,或者说一个运行环境吧。Win32 最初是与 16 位的 Win16 相对的,与 Win16 有很大差别,所以专门称作 Win32 。后来 Windows 出了 64 位后,改动并不大,和 32 位的 Win32 基本是兼容的,所以后来 Win32 也可以包含 64 位。Win32 应用就是指使用 Win32 API ,或者说在 Win32 环境下运行的应用。
    现在 Win32 一般是和 UWP 相对的,UWP 也可以理解为一个运行环境,在这个环境中运行的应用只能调用 UWP API ,UWP API 和 Win32 API 是部分重合的,也就是说有的 API 两边都能使用,有的只有其中一边能用。一个 WinRT class 有 DualApiPartitionAttribute 代表 UWP 和 Win32 都能使用,不过没有的话不一定不可以使用。
    Electron 开发的应用是 Win32 应用,所以如果某个 API 只能在 UWP 环境下使用,就意味着 Electron 用不了。
    DOLLOR
        14
    DOLLOR  
       50 天前   ❤️ 1
    如果厂商提供 dll 文件的话,用 node-ffi-napi 是最方便的方法。
    不过你可能还需要看得懂用 C++作为样例编写的文档。

    比如微软官网
    https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxa
    文档上的参数声明是这样写的
    int MessageBoxA(
    [in, optional] HWND hWnd,
    [in, optional] LPCSTR lpText,
    [in, optional] LPCSTR lpCaption,
    [in] UINT uType
    );

    那么你就可以根据这个声明,构造出在 JS 接口
    const user32 = ffi.Library('user32', {
    MessageBoxA: ['int', ['int', 'string', 'string', 'int']],
    });

    然后就可以这样调用它
    user32.MessageBoxA(
    0,
    'hello',
    'title',
    0x00000001 | 0x00000020
    )
    milkleeeeee
        15
    milkleeeeee  
    OP
       50 天前
    @DOLLOR #14 感谢,这下我更清楚了……不过我看了下 node-ffi-napi ,它也是好几年没人维护了,且从 issues 来看,不支持 macOS 的 arm64 版本,看起来没法满足我的需求
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2457 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 13:01 · PVG 21:01 · LAX 06:01 · JFK 09:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.