program.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. from __future__ import annotations
  2. from typing import Any
  3. from ... import windows_automation
  4. from ..context import WorkflowContext
  5. from ..registry import control_ports, field_def, register_node
  6. def start_program_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  7. params = node.get("params", {})
  8. command = str(inputs.get("command", params.get("command")) or "")
  9. result = windows_automation.start_program(
  10. command=command,
  11. cwd=inputs.get("cwd", params.get("cwd")),
  12. shell=bool(inputs.get("shell", params.get("shell", True))),
  13. )
  14. context.remember_pid(result.get("pid"))
  15. return result
  16. def stop_program_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  17. params = node.get("params", {})
  18. pid = inputs.get("pid", params.get("pid"))
  19. result = windows_automation.stop_program(
  20. pid=int(pid) if pid not in (None, "") else None,
  21. name=inputs.get("name", params.get("name")),
  22. timeout_seconds=float(params.get("timeout_seconds", 8)),
  23. kill_after_timeout=bool(params.get("kill_after_timeout", True)),
  24. )
  25. return result
  26. def close_opened_programs_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  27. closed = []
  28. for pid in list(context.opened_pids):
  29. try:
  30. closed.append(windows_automation.stop_program(pid=pid))
  31. except Exception as exc:
  32. closed.append({"pid": pid, "error": str(exc)})
  33. finally:
  34. if pid in context.opened_pids:
  35. context.opened_pids.remove(pid)
  36. return {"action": "close_opened_programs", "items": closed}
  37. def open_url_node(node: dict[str, Any], inputs: dict[str, Any], context: WorkflowContext) -> dict[str, Any]:
  38. params = node.get("params", {})
  39. result = windows_automation.open_url(
  40. url=str(inputs.get("url", params.get("url")) or ""),
  41. browser=inputs.get("browser", params.get("browser")),
  42. new_window=bool(inputs.get("new_window", params.get("new_window", True))),
  43. )
  44. context.remember_pid(result.get("pid"))
  45. return result
  46. register_node(
  47. {
  48. "type": "browser.open_url",
  49. "category": "program",
  50. "label": "打开网页",
  51. "params": {
  52. "url": field_def("text", "网址", "https://example.com", required=True),
  53. "browser": field_def("select", "浏览器", "default", options=["default", "edge"]),
  54. "new_window": field_def("boolean", "新窗口", True),
  55. },
  56. "inputs": {
  57. "url": field_def("string", "网址"),
  58. "browser": field_def("string", "浏览器"),
  59. "new_window": field_def("boolean", "新窗口"),
  60. },
  61. "outputs": {
  62. "url": {"type": "string", "label": "网址"},
  63. "browser": {"type": "string", "label": "浏览器"},
  64. "pid": {"type": "number", "label": "启动进程 PID"},
  65. },
  66. "control_ports": control_ports(),
  67. },
  68. open_url_node,
  69. )
  70. register_node(
  71. {
  72. "type": "program.start",
  73. "category": "program",
  74. "label": "启动程序",
  75. "params": {
  76. "command": field_def("text", "命令", "notepad", required=True),
  77. "cwd": field_def("text", "工作目录"),
  78. "shell": field_def("boolean", "使用 Shell", True),
  79. },
  80. "inputs": {
  81. "command": field_def("string", "命令"),
  82. "cwd": field_def("string", "工作目录"),
  83. "shell": field_def("boolean", "使用 Shell"),
  84. },
  85. "outputs": {
  86. "pid": {"type": "number", "label": "进程 PID"},
  87. "command": {"type": "string", "label": "命令"},
  88. "cwd": {"type": "string", "label": "工作目录"},
  89. },
  90. "control_ports": control_ports(),
  91. },
  92. start_program_node,
  93. )
  94. register_node(
  95. {
  96. "type": "program.stop",
  97. "category": "program",
  98. "label": "关闭程序",
  99. "params": {
  100. "pid": field_def("number", "PID"),
  101. "name": field_def("text", "进程名"),
  102. "timeout_seconds": field_def("number", "等待秒数", 8, minimum=0, maximum=60),
  103. "kill_after_timeout": field_def("boolean", "超时后强制结束", True),
  104. },
  105. "inputs": {"pid": field_def("number", "PID"), "name": field_def("string", "进程名")},
  106. "outputs": {"matched": {"type": "number", "label": "匹配数量"}, "items": {"type": "array", "label": "关闭结果"}},
  107. "control_ports": control_ports(),
  108. },
  109. stop_program_node,
  110. )
  111. register_node(
  112. {
  113. "type": "program.close_opened",
  114. "category": "program",
  115. "label": "关闭本流程打开的程序",
  116. "params": {},
  117. "inputs": {},
  118. "outputs": {"items": {"type": "array", "label": "关闭结果"}},
  119. "control_ports": control_ports(),
  120. },
  121. close_opened_programs_node,
  122. )