quickwin 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +7 -7
- package/README.md +7 -7
- package/constants.ts +1063 -0
- package/enum_map.d.ts +129 -0
- package/examples/PdfCanvas.js +2 -2
- package/examples/PdfCanvas.tsx +3 -2
- package/examples/{execd.js → execd/main.js} +563 -122
- package/examples/execd/tray.js +192 -0
- package/examples/{execd_worker.js → execd/worker.js} +7 -7
- package/examples/pdf_preview2.js +46 -46
- package/examples/pdf_preview2.ts +55 -54
- package/examples/pdf_viewer.js +34 -19
- package/examples/pdf_viewer.tsx +6 -5
- package/examples/test_gallery.js +35 -20
- package/examples/test_gallery.tsx +9 -8
- package/examples/test_react_lazy.js +34 -19
- package/examples/test_react_lazy.tsx +7 -6
- package/examples/test_react_listbox.js +34 -19
- package/examples/test_react_listbox.tsx +8 -7
- package/examples/test_root_window.js +34 -19
- package/examples/test_root_window.tsx +5 -5
- package/examples/test_tab.js +34 -19
- package/examples/test_tab.tsx +7 -6
- package/examples/tray_demo.js +8 -8
- package/examples/tray_demo.tsx +9 -8
- package/lib/dumpRects.js +2 -2
- package/lib/dumpRects.ts +3 -2
- package/lib/fetch.js +15 -15
- package/lib/fetch.ts +16 -15
- package/lib/ffi/bind.js +3 -3
- package/lib/ffi/bind.ts +3 -3
- package/lib/http-server.js +4 -4
- package/lib/http-server.ts +5 -4
- package/lib/react-qw/components/Button.js +2 -2
- package/lib/react-qw/components/CheckBox.js +4 -4
- package/lib/react-qw/components/ComboBox.js +10 -10
- package/lib/react-qw/components/DateTimePicker.js +12 -12
- package/lib/react-qw/components/Input.js +7 -7
- package/lib/react-qw/components/Link.js +4 -4
- package/lib/react-qw/components/ListBox.js +12 -12
- package/lib/react-qw/components/ListView.js +35 -35
- package/lib/react-qw/components/PathPicker.js +3 -3
- package/lib/react-qw/components/ProgressBar.js +4 -4
- package/lib/react-qw/components/RadioButton.js +4 -4
- package/lib/react-qw/components/ScrollView.js +28 -28
- package/lib/react-qw/components/Slider.js +11 -11
- package/lib/react-qw/components/Tab.js +10 -10
- package/lib/react-qw/components/Tooltip.js +8 -8
- package/lib/react-qw/components/TreeView.js +20 -20
- package/lib/react-qw/index.js +5 -5
- package/lib/react-qw/index.ts +6 -5
- package/lib/react-qw/props.js +4 -4
- package/lib/react-qw/props.ts +5 -4
- package/lib/react-qw/reconciler.js +10 -10
- package/lib/react-qw/reconciler.ts +11 -10
- package/lib/text-measure.js +3 -3
- package/lib/text-measure.ts +4 -3
- package/lib/websocket.js +17 -17
- package/lib/websocket.ts +18 -17
- package/lib/windows/advapi32.js +7 -7
- package/lib/windows/advapi32.ts +7 -7
- package/lib/windows/gdi32.js +16 -16
- package/lib/windows/gdi32.ts +16 -16
- package/lib/windows/kernel32.js +41 -2
- package/lib/windows/kernel32.ts +45 -2
- package/lib/windows/shell32.js +24 -3
- package/lib/windows/shell32.ts +27 -4
- package/lib/windows/structs.js +54 -0
- package/lib/windows/structs.ts +63 -1
- package/lib/windows/user32.js +18 -6
- package/lib/windows/user32.ts +18 -6
- package/lib/windows/winspool.js +3 -3
- package/lib/windows/winspool.ts +3 -3
- package/package.json +4 -3
- package/quickwin.d.ts +32 -10
- package/qwin-nowasm-x86.exe +0 -0
- package/qwin-nowasm.exe +0 -0
- package/qwin-x86.exe +0 -0
- package/qwin.exe +0 -0
- package/test/test_ffi_bind.js +7 -7
- package/test/test_ffi_bind.ts +8 -8
- package/test/test_ffi_struct.js +2 -2
- package/test/test_ffi_struct.ts +3 -3
- package/test/test_ffi_windows.js +1 -1
- package/test/test_ffi_windows.ts +1 -1
- package/test/test_files.js +7 -7
- package/test/test_files.ts +8 -8
- package/test/test_gdi_draw.js +51 -51
- package/test/test_gdi_draw.ts +57 -57
- package/test/test_http_server.js +3 -3
- package/test/test_http_server.ts +4 -3
- package/test/test_ipv6.js +3 -3
- package/test/test_ipv6.ts +4 -3
- package/test/test_net_event.js +3 -3
- package/test/test_net_event.ts +4 -3
- package/test/test_printer.js +4 -4
- package/test/test_printer.ts +5 -5
- package/test/test_react_complex.js +36 -21
- package/test/test_react_counter.js +34 -19
- package/test/test_react_flex.js +36 -21
- package/test/test_react_hidden.js +34 -19
- package/test/test_react_listview_link.js +35 -20
- package/test/test_react_notify.js +52 -37
- package/test/test_react_render.js +34 -19
- package/test/test_registry.js +6 -6
- package/test/test_registry.ts +8 -8
- package/test/test_wolfssl_read.js +8 -8
- package/test/test_wolfssl_read.ts +9 -8
- package/examples/execd.tsx +0 -798
- package/examples/execd_worker.ts +0 -127
- package/quickwin_const.d.ts +0 -1063
package/examples/execd_worker.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import * as os from 'os'
|
|
2
|
-
import * as std from 'std'
|
|
3
|
-
import { WCHAR } from '../lib/ffi/bind.js'
|
|
4
|
-
import { NULL, PtrArrayBuffer } from '../lib/ffi/ctype.js'
|
|
5
|
-
import { struct } from '../lib/ffi/struct.js'
|
|
6
|
-
import {
|
|
7
|
-
CloseHandle, CreatePipe, CreateProcess, GetExitCodeProcess, GetLastError, GetSystemDirectory,
|
|
8
|
-
ReadFile, SetHandleInformation, WaitForSingleObject,
|
|
9
|
-
} from '../lib/windows/kernel32.js'
|
|
10
|
-
import { PROCESS_INFORMATION, STARTUPINFOW } from '../lib/windows/structs.js'
|
|
11
|
-
|
|
12
|
-
// worker 没有可观测的输出通道:绑定失败会静默中断 worker 脚本,主线程永远等不到消息。
|
|
13
|
-
// 失败原因落盘 diag.log 以便定位(典型:DLL 位数与进程不匹配 -> ERROR_BAD_EXE_FORMAT 193)。
|
|
14
|
-
const diagFile = (stage: string): void => {
|
|
15
|
-
try {
|
|
16
|
-
const f = std.open('diag.log', 'a')
|
|
17
|
-
if (f) { f.puts(`${Date.now()} ${stage}\n`); f.close() }
|
|
18
|
-
} catch (ex) { /* best effort */ }
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const HANDLE_FLAG_INHERIT = 0x1
|
|
22
|
-
const STARTF_USESTDHANDLES = 0x100
|
|
23
|
-
const WAIT_INFINITE = 0xffffffff
|
|
24
|
-
// STARTUPINFOW / PROCESS_INFORMATION 的布局随进程位宽(x86 68B / x64 104B),由 struct 按 os.arch 推。
|
|
25
|
-
// os.arch 是编译期的进程指针宽度(quickjs-libc.c OS_ARCH),WOW64 下的 32 位进程得 ia32 布局——
|
|
26
|
-
// 本地 win7 VM 上的 execd 就是 32 位进程跑在 64 位系统上。
|
|
27
|
-
|
|
28
|
-
const parent = os.Worker.parent
|
|
29
|
-
|
|
30
|
-
// GetSystemDirectoryW 拼 cmd.exe 全路径。
|
|
31
|
-
// 探针实测(XP/Win7 均如此):CreateProcessW 的 lpCommandLine 第一个 token 若是
|
|
32
|
-
// 裸 "cmd.exe",PATH 解析在本环境失败(err 267 ERROR_DIRECTORY / 123 ERROR_INVALID_NAME),
|
|
33
|
-
// 用全路径即正常。cmd 内部再解析 ping/dir 等用自己的 PATH,无此问题。
|
|
34
|
-
let sysDir = 'C:\\Windows\\System32'
|
|
35
|
-
try {
|
|
36
|
-
const out = WCHAR.alloc(256)
|
|
37
|
-
const n = GetSystemDirectory(out, 256)
|
|
38
|
-
const s = n > 0 ? WCHAR.decode(out) : ''
|
|
39
|
-
if (s) sysDir = s
|
|
40
|
-
} catch (ex) {
|
|
41
|
-
diagFile('SYS-DIR-FAIL: ' + String(ex))
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// 用 CreateProcessW + CreatePipe 直接捕获子进程 stdout(替代 winpty)。
|
|
45
|
-
// 纯捕获场景(/exec 从不交互),管道方案比 winpty 少一层 agent 中转:
|
|
46
|
-
// - 流式粒度更好:探针实测 XP 上逐行实时到达(winpty 攒批 ~4s)
|
|
47
|
-
// - 无 winpty.dll / winpty-agent.exe 依赖,纯 kernel32
|
|
48
|
-
// 编码:无统一代码页转换——cmd 内置经 /u 恒为 UTF-16LE,外部程序各自原生
|
|
49
|
-
// (qwin= UTF-8、中文系统工具= GBK),客户端按来源分别解码。
|
|
50
|
-
// 同步阻塞读循环(worker 线程自转),主线程事件循环不受影响。
|
|
51
|
-
// CreatePipe 的两个 HANDLE 出参槽:一个结构两个指针字段,读回走 decode
|
|
52
|
-
// CreatePipe 成功后两端句柄必非零(失败已在下方 throw)——字段标 '!',decode 直出 Ptr
|
|
53
|
-
const PIPE_HANDLES = /* @__PURE__ */ struct('PIPE_HANDLES', { hRead: '<HFILE>ptr!', hWrite: '<HFILE>ptr!' })
|
|
54
|
-
|
|
55
|
-
function runCmd(id: number, cmd: string): number {
|
|
56
|
-
// —— 管道 + 继承设置(读端不可继承,否则 EOF 永不触发)——
|
|
57
|
-
const pipe = PIPE_HANDLES.alloc()
|
|
58
|
-
if (!CreatePipe(pipe.ptr, pipe.ptr + PIPE_HANDLES.offsetOf('hWrite'), NULL, 0)) {
|
|
59
|
-
throw new Error('CreatePipe err=' + GetLastError())
|
|
60
|
-
}
|
|
61
|
-
const { hRead, hWrite } = PIPE_HANDLES.decode(pipe)
|
|
62
|
-
SetHandleInformation(hWrite, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)
|
|
63
|
-
SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0)
|
|
64
|
-
|
|
65
|
-
// —— STARTUPINFO(写端作为子进程 stdout/stderr)——
|
|
66
|
-
const pi = PROCESS_INFORMATION.alloc()
|
|
67
|
-
// 恒加 /u:cmd 内置输出(echo/dir/type 与 cmd 自身报错)直接写 UTF-16LE,绕开「按代码页
|
|
68
|
-
// 编码成字节」这一步(Tiny11 缺 NLS 时中文变 ?;win7/XP 的 GBK 无损只是 ACP=936 的 locale 巧合)。
|
|
69
|
-
// /u 在所有 Win 版本行为一致,故不分版本——早期用 RtlGetVersion 判 NT>=10 只对 win11 加 /u,已删。
|
|
70
|
-
// 外部程序(qwin/ping 等)输出仍为各自原生编码,/u 不参与(实测 ping 仍透传 GBK)。见 .agents/CMD_ENCODING_ACP_NLS.md §8。
|
|
71
|
-
const cmdline = `${sysDir}\\cmd.exe /u /c ${cmd}`
|
|
72
|
-
if (!CreateProcess(NULL, cmdline, NULL, NULL, 1, 0, NULL, NULL,
|
|
73
|
-
{ cb: STARTUPINFOW.size, dwFlags: STARTF_USESTDHANDLES, hStdOutput: hWrite, hStdError: hWrite }, pi.ptr)) {
|
|
74
|
-
CloseHandle(hRead)
|
|
75
|
-
CloseHandle(hWrite)
|
|
76
|
-
throw new Error('CreateProcessW err=' + GetLastError() + ' cmd=' + cmdline)
|
|
77
|
-
}
|
|
78
|
-
const { hProcess, hThread, dwProcessId } = PROCESS_INFORMATION.decode(pi)
|
|
79
|
-
CloseHandle(hThread)
|
|
80
|
-
CloseHandle(hWrite)
|
|
81
|
-
parent.postMessage({ type: 'info', id, pid: dwProcessId })
|
|
82
|
-
|
|
83
|
-
// —— 同步阻塞读循环(子进程树全退出、写端全关 -> EOF -> 收尾)——
|
|
84
|
-
const bufB = new PtrArrayBuffer(4096)
|
|
85
|
-
const buf = new Uint8Array(bufB)
|
|
86
|
-
const nReadB = new PtrArrayBuffer(4)
|
|
87
|
-
const nRead = new Uint32Array(nReadB)
|
|
88
|
-
for (;;) {
|
|
89
|
-
nRead[0] = 0
|
|
90
|
-
if (!ReadFile(hRead, bufB, 4096, nReadB, NULL)) break
|
|
91
|
-
const n = nRead[0]!
|
|
92
|
-
if (n === 0) break
|
|
93
|
-
parent.postMessage({ type: 'data', id, chunk: buf.slice(0, n) })
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
WaitForSingleObject(hProcess, WAIT_INFINITE)
|
|
97
|
-
const ecB = new PtrArrayBuffer(4)
|
|
98
|
-
const ec = new Int32Array(ecB)
|
|
99
|
-
GetExitCodeProcess(hProcess, ecB)
|
|
100
|
-
const code = ec[0]!
|
|
101
|
-
CloseHandle(hRead)
|
|
102
|
-
CloseHandle(hProcess)
|
|
103
|
-
return code
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
parent.onmessage = (e) => {
|
|
107
|
-
// worker 只剩 /exec 一个租客:外部命令不可控,必须与主进程隔离(长阻塞无上界)。
|
|
108
|
-
// 内置端点(截屏/窗口列表/改分辨率)全部在主进程同步跑——bug 当场 throw → 500,
|
|
109
|
-
// 而不是在 worker 里静默挂掉等 timer 兜底成 504。
|
|
110
|
-
const msg = e.data as { type: string; id: number; cmd?: string }
|
|
111
|
-
if (msg.type === 'run' && typeof msg.cmd === 'string') {
|
|
112
|
-
let code = -1
|
|
113
|
-
let error: string | null = null
|
|
114
|
-
try {
|
|
115
|
-
code = runCmd(msg.id, msg.cmd)
|
|
116
|
-
} catch (ex) {
|
|
117
|
-
error = String(ex)
|
|
118
|
-
}
|
|
119
|
-
parent.postMessage({ type: 'result', id: msg.id, code, error })
|
|
120
|
-
}
|
|
121
|
-
// 父侧每个请求起一个新 worker,一次只处理一个请求,处理完立刻释放自己的 port:
|
|
122
|
-
// port_list 清空后 js_os_poll 返回 -1(quickjs-libc.c:2506)→ 本线程退出,
|
|
123
|
-
// JSRuntime 随之释放。不设 null 的话线程常驻(实测 win7 30 次请求线程 4→35)。
|
|
124
|
-
// 注意父侧 `worker.onmessage = null` 只释放父侧 port,对本线程无效——必须在这里设。
|
|
125
|
-
// 消息已在 js_post_message_pipe 进队列,父侧读的是同一份 refcount 共享管道,线程退出不影响。
|
|
126
|
-
parent.onmessage = null
|
|
127
|
-
}
|