node-process-watcher
Advanced tools
+1
-1
@@ -108,3 +108,3 @@ export interface process_info { | ||
| launch_process_as_user_for_win_service(exe_path: string, args?: string, cwd?: string): number; | ||
| launch_process_as_user_for_win_service_console(exe_path: string, args: string, cwd: string, on_data: (data: string) => void, on_pid: (pid: number) => void, on_done: () => void): void; | ||
| launch_process_as_user_for_win_service_console(exe_path: string, args: string, cwd: string, on_data: (data: string) => void, on_done: () => void, on_pid: (pid: number) => void): void; | ||
| get_all_processes(): { | ||
@@ -111,0 +111,0 @@ pid: number; |
+1
-1
| { | ||
| "name": "node-process-watcher", | ||
| "version": "1.7.3", | ||
| "version": "1.7.4", | ||
| "description": "Get process information in real time", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
+59
-81
@@ -925,17 +925,14 @@ #ifdef _WIN32 | ||
| Napi::Function dataCallback, | ||
| Napi::Function pidCallback, | ||
| Napi::Function doneCallback) | ||
| : Napi::AsyncWorker(doneCallback), | ||
| exe_path_(exe_path), | ||
| args_(args), | ||
| cwd_(cwd), | ||
| Napi::Function doneCallback, | ||
| Napi::Function pidCallback | ||
| ) | ||
| : Napi::AsyncWorker(doneCallback), // AsyncWorker 的默认回调用作完成回调 | ||
| exe_path_(exe_path), args_(args), cwd_(cwd), | ||
| tsfn_(Napi::ThreadSafeFunction::New(env, dataCallback, "OnData", 0, 1)), | ||
| pid_callback_(Napi::Persistent(pidCallback)) | ||
| { | ||
| pid_callback_.SuppressDestruct(); | ||
| } | ||
| tsfn_1(Napi::ThreadSafeFunction::New(env, pidCallback, "OnPid", 0, 1)) | ||
| {} | ||
| ~ProcessWorker() { | ||
| tsfn_.Release(); | ||
| pid_callback_.Reset(); | ||
| tsfn_1.Release(); | ||
| } | ||
@@ -963,65 +960,52 @@ | ||
| // 获取当前活动用户 Session | ||
| DWORD sessionId = WTSGetActiveConsoleSessionId(); | ||
| HANDLE userToken = NULL; | ||
| if (!WTSQueryUserToken(sessionId, &userToken)) { | ||
| CloseHandle(hStdOutRead); | ||
| CloseHandle(hStdOutWrite); | ||
| SetError("Failed to query user token"); | ||
| return; | ||
| } | ||
| WTSQueryUserToken(sessionId, &userToken); | ||
| HANDLE primaryToken = NULL; | ||
| if (!DuplicateTokenEx( | ||
| userToken, | ||
| TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID, | ||
| NULL, | ||
| SecurityImpersonation, | ||
| TokenPrimary, | ||
| &primaryToken)) { | ||
| CloseHandle(hStdOutRead); | ||
| CloseHandle(hStdOutWrite); | ||
| CloseHandle(userToken); | ||
| SetError("Failed to duplicate user token"); | ||
| return; | ||
| } | ||
| DuplicateTokenEx( | ||
| userToken, | ||
| TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID, | ||
| NULL, | ||
| SecurityImpersonation, | ||
| TokenPrimary, | ||
| &primaryToken); | ||
| LPVOID environment = NULL; | ||
| if (!CreateEnvironmentBlock(&environment, primaryToken, FALSE)) { | ||
| environment = NULL; | ||
| } | ||
| if (!CreateEnvironmentBlock(&environment, primaryToken, FALSE)) { | ||
| environment = NULL; | ||
| } | ||
| DWORD flags = CREATE_UNICODE_ENVIRONMENT; | ||
| DWORD flags = CREATE_UNICODE_ENVIRONMENT; | ||
| BOOL ok = CreateProcessAsUserW( | ||
| primaryToken, | ||
| NULL, | ||
| cmd.data(), | ||
| NULL, | ||
| NULL, | ||
| TRUE, | ||
| flags, | ||
| environment, | ||
| cwd_.empty() ? nullptr : cwd_.c_str(), | ||
| &si, | ||
| &pi | ||
| ); | ||
| CloseHandle(hStdOutWrite); | ||
| BOOL ok = CreateProcessAsUserW( | ||
| primaryToken, | ||
| NULL, | ||
| cmd.data(), | ||
| NULL, | ||
| NULL, | ||
| TRUE, | ||
| flags, | ||
| environment, | ||
| cwd_.empty() ? nullptr : cwd_.c_str(), | ||
| &si, | ||
| &pi | ||
| ); | ||
| CloseHandle(hStdOutWrite); // 关闭写端,子进程可以写 | ||
| if (environment) DestroyEnvironmentBlock(environment); | ||
| CloseHandle(primaryToken); | ||
| CloseHandle(userToken); | ||
| CloseHandle(primaryToken); | ||
| CloseHandle(userToken); | ||
| if (!ok) { | ||
| CloseHandle(hStdOutRead); | ||
| SetError("Failed to create process as user"); | ||
| return; | ||
| } | ||
| tsfn_1.BlockingCall([pi](Napi::Env env, Napi::Function jsCallback) { | ||
| jsCallback.Call({ Napi::Number::New(env, pi.dwProcessId) }); | ||
| }); | ||
| const DWORD pid = pi.dwProcessId; | ||
| pid_ = pid; | ||
| char buffer[4096]; | ||
| DWORD bytesRead; | ||
| while (ReadFile(hStdOutRead, buffer, sizeof(buffer)-1, &bytesRead, nullptr) && bytesRead > 0) { | ||
| // buffer[bytesRead] = '\0'; | ||
| if(bytesRead==0) break; | ||
| std::string output(buffer, bytesRead); | ||
@@ -1040,9 +1024,2 @@ | ||
| void OnOK() override { | ||
| if (!pid_callback_.IsEmpty()) { | ||
| pid_callback_.Call({ Napi::Number::New(Env(), pid_) }); | ||
| } | ||
| Napi::AsyncWorker::OnOK(); | ||
| } | ||
| private: | ||
@@ -1053,6 +1030,6 @@ std::wstring exe_path_; | ||
| Napi::ThreadSafeFunction tsfn_; | ||
| Napi::FunctionReference pid_callback_; | ||
| DWORD pid_ = 0; | ||
| Napi::ThreadSafeFunction tsfn_1; | ||
| }; | ||
| }; | ||
| Napi::Value LaunchUserConsoleProcess(const Napi::CallbackInfo& info) { | ||
@@ -1062,4 +1039,4 @@ Napi::Env env = info.Env(); | ||
| // 参数数量检查 | ||
| if (info.Length() < 6) { | ||
| Napi::TypeError::New(env, "Expected 6 arguments: exePath, args, cwd, dataCallback, pidCallback, doneCallback").ThrowAsJavaScriptException(); | ||
| if (info.Length() < 5) { | ||
| Napi::TypeError::New(env, "Expected 5 arguments: exePath, args, cwd, dataCallback, doneCallback").ThrowAsJavaScriptException(); | ||
| return env.Null(); | ||
@@ -1099,16 +1076,18 @@ } | ||
| // pidCallback | ||
| // doneCallback | ||
| if (!info[4].IsFunction()) { | ||
| Napi::TypeError::New(env, "pidCallback must be a function").ThrowAsJavaScriptException(); | ||
| Napi::TypeError::New(env, "doneCallback must be a function").ThrowAsJavaScriptException(); | ||
| return env.Null(); | ||
| } | ||
| Napi::Function pidCallback = info[4].As<Napi::Function>(); | ||
| Napi::Function doneCallback = info[4].As<Napi::Function>(); | ||
| // doneCallback | ||
| // pidCallback | ||
| if (!info[5].IsFunction()) { | ||
| Napi::TypeError::New(env, "doneCallback must be a function").ThrowAsJavaScriptException(); | ||
| return env.Null(); | ||
| Napi::TypeError::New(env, "pidCallback must be a function").ThrowAsJavaScriptException(); | ||
| return env.Null(); | ||
| } | ||
| Napi::Function doneCallback = info[5].As<Napi::Function>(); | ||
| ProcessWorker* worker = new ProcessWorker(env, exe_path, args, cwd, dataCallback, pidCallback, doneCallback); | ||
| Napi::Function pidCallback = info[4].As<Napi::Function>(); | ||
| // 创建并队列异步任务 | ||
| ProcessWorker* worker = new ProcessWorker(env, exe_path, args, cwd, dataCallback, doneCallback,pidCallback); | ||
| worker->Queue(); | ||
@@ -1122,2 +1101,1 @@ | ||
| #endif | ||
+2
-2
@@ -131,4 +131,4 @@ const native = require("../build/Release/node-process-watcher.node") | ||
| on_data: (data: string)=>void, | ||
| on_pid: (pid: number)=>void, | ||
| on_done: ()=>void | ||
| on_done: ()=>void, | ||
| on_pid: (pid: number)=>void | ||
| ):void; | ||
@@ -135,0 +135,0 @@ |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
107494
-0.25%1
Infinity%