ACCESS DENIED when using serialport in node-red

SerialPort Version
12.0.0

Node Version
V18.16.1 (MACOS) V20.15.0(WIN10,WIN11 )

Electron Version
No response

Platform
MACOS12.1 WIN11 WIN10

Architecture
x64

Hardware or chipset of serialport
FT232R USB UART

I use serialport and I use it in node-red MACOS OS,and it runs good. But when It runs on WIN10 or WIN11 , it occurs some problems. ACCESS DENIED. It took me 3days ,and finally I found .When I close the port ,even add await function ,It still cant close clearly.I have to add some delay to solve the problem.
So can anyone find the solution?
The json code:

[
    {
        "id": "babef08263e2071a",
        "type": "function",
        "z": "f9e5abd85425a547",
        "name": "single",
        "func": "var { SerialPort } = global.get('require')('serialport');\nvar delay = 150\nconst receiveDelay = delay;  // 接收延迟时间,单位:毫秒\nconst writeDelay = delay;  // 接收延迟时间,单位:毫秒\n// serialport profile 获取串口配置\nvar portConfig = {\n    port: \"COM3\",   // 串口名称,请根据实际情况修改\n    baudRate: 2400,\n    dataBits: 8,\n    stopBits: 1,\n    parity: \"None\",\n};\n\n// instance ,创建串口实例\nvar port \nnode.warn(\"@@@ msg:\")\n\ntry {\n        port = new SerialPort({\n        path: portConfig.port,\n        baudRate: portConfig.baudRate,\n        dataBits: portConfig.dataBits,\n        stopBits: portConfig.stopBits,\n        parity: portConfig.parity,\n    });\n    \n    // node.warn('@@flow.get(port_flow1):' + flow.get('port_flow1'));\n    // port=flow.get('port_flow1')||0;\n    // port = new SerialPort({\n    //     path: portConfig.port,\n    //     baudRate: portConfig.baudRate,\n    //     dataBits: portConfig.dataBits,\n    //     stopBits: portConfig.stopBits,\n    //     parity: portConfig.parity,\n    // }); \n    // flow.set(\"port_flow1\",port)\n    node.warn('@@port.isOpen?:' + port.isOpen);\n\n} catch (error) {\n    node.warn('开启串口时发生错误:' + error);\n    getStackTrace();\n    onClose();\n};\n\n//send data async 发送数据的异步函数\nvar sendData = async function (data) {\n    return new Promise(function (resolve, reject) {\n        try {\n            port.write(data, function (err) {\n                if (err) {\n                    reject(err);\n                } else {\n                    resolve();\n                }\n            });\n        } catch (error) {\n            getStackTrace();\n            onClose()\n        }finally{\n        }\n    });\n};\n\n//receive data sync 接收数据的异步函数\nvar receiveData = async function () {\n    return new Promise(function (resolve) {\n        var dataTimeout = setTimeout(function () {\n            //a delay not wait 设置一个超时,防止永远等待\n            resolve('');\n        }, receiveDelay);\n        try {\n            port.on('data', function (data) {\n                clearTimeout(dataTimeout);\n                resolve(data.toString('hex'));\n            });\n        } catch (error) {\n            getStackTrace();\n            onClose()\n            node.warn(\"@@@receiveData catch\")\n        } finally {\n        }\n    });\n};\n// main 主处理逻辑\nasync function processInput(msg) {\n    try {\n        // send data发送数据\n        var temp_command = '010300000001840A '\n        var dataToSend = Buffer.from(temp_command, 'hex');\n        await sendData(dataToSend);\n        // 等待1秒\n        await new Promise(function (resolve) {\n            setTimeout(resolve, writeDelay);\n        });\n        // 接收数据\n        var receivedData = await receiveData();\n        // 返回结果\n        if (receivedData!='')\n        {\n            node.warn(\"@received:\" + receivedData);\n        }\n    } catch (error) {\n        // 发生错误时处理\n        node.error(error.message, msg);\n    }finally{\n            onClose().then(()=>{ //then添加\n            node.warn(\"@@@then\")\n            node.warn('@@sending msg port.isOpen?:' + port.isOpen);\n                node.send(msg);\n             })\n    }\n}\n// 在节点关闭时关闭串口\nasync function onClose() {\n    node.warn('@@@ port is closing');\n    if (port.isOpen) {\n        port.close((err) => {\n            if (err) {\n                node.warn('关闭串口时发生错误:' + err.message);\n            } else {\n                node.warn('串口成功关闭');\n                node.warn('关闭port.isOpen:' + port.isOpen);\n            }\n        });\n    }\n    else{\n        node.warn('串口早已关闭');\n    }\n}\n\nvar getStackTrace = function() {\n  var obj = {};\n  Error.captureStackTrace(obj, getStackTrace);\n  node.warn(\"Location:\" + (obj.stack).split(/\\n+/)[1].replace(/(^\\s+|\\s+$)/,\"\"));\n};\n\ntry {\n    getStackTrace();\n    processInput(msg);\n} catch (error) {\n    node.warn('processInput 发生错误:' + error.message);\n}finally{\n    getStackTrace();\n    onClose()\n}\n\n// 在 Function 节点中监听关闭事件,用于关闭串口\nnode.on('close', function () {\n    // node.warn('close');\n    getStackTrace();\n    onClose();\n});\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 455.4513854980469,
        "y": 280.44964599609375,
        "wires": [
            []
        ]
    },
    {
        "id": "7bd41a4973ab38d1",
        "type": "inject",
        "z": "f9e5abd85425a547",
        "name": "",
        "props": [
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 315.4513854980469,
        "y": 280.44964599609375,
        "wires": [
            [
                "babef08263e2071a"
            ]
        ]
    }
]

You can touch the inject button to test,when you touch too fast ,it occurs "[red] Uncaught Exception:
[error] Error: Opening COM3: Access denied"

Maybe need to call done() when you have finished closing the port so the rest of the runtime knows. eg see the serial port node code - node-red-nodes/io/serialport/25-serial.js at cd6bbb3e69e74d17db4e4e98ad6a6b68ba6b008b · node-red/node-red-nodes · GitHub

Many thanks,I try it now

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.