# Builtin - 资源 / 进程 ## `sleep(milliseconds)` 声明:function 暂停执行。 | 参数 | 类型 | 说明 | | -------------- | ------- | --------------------------------------------------- | | `milliseconds` | integer | 整数,需要暂停的毫秒数。例如暂停一秒为Sleep(1000)。 | 返回:nil ### 示例 ```tsl // 以下代码先打印123,接着回暂停2S,然后接着打印456 echo 123; sleep(2000); echo 456; ``` ## `sysParamStr(index)` 声明:function 获得命令行的指定索引的参数值。 | 参数 | 类型 | 说明 | | ------- | ---- | ---------------------------------------------------------------------------------------------------------------------- | | `index` | | 整数,命令行参数的索引号。Index=0,返回值为当前天软脚本文件名称;Index>0,返回值为额外传入的命令行参数值(字符串类型) | 返回:string ### 示例 ```tsl // 本地test.tsl文件中代码如下: test(); function test(); begin r := array(); for i := 1 to sysParamcount() do begin echo sysParamStr(i), '\r\n'; end end // 在cmd中打开文件所在文件夹,输入命令:tsl test.tsl 1 2 3 ``` ## `sysReleaseMutex(mutex)` 声明:function 释放一个互斥锁。 | 参数 | 类型 | 说明 | | ------- | ------- | ---------------- | | `mutex` | integer | 整数,互斥锁编号 | 返回:bool ### 示例 ```tsl // 释放互斥锁,参数为创建互斥锁时返回的互斥锁编号 ret := rdo2 sysCreateMutex("tinysoft"); ret1 := rdo2 sysReleaseMutex(ret); return ret1; // 输出:1 ``` ## `sysexecnewpipe(flag)` 声明:function 创建Sysexec进程的管道。参数缺省时,默认创建读写管道。创建之后会与第一次被用的进程进行绑定,当有多个Sysexec进程时,可以创建多个管道分别进行读写操作。 | 参数 | 类型 | 说明 | | ------ | ------- | ---------------------------------------------------------------------------------------------------- | | `flag` | integer | 整数,可选参数,控制创建管道的读写属性。Flag转换为二进制时,第0位表示是否可读,第1位表示是否可写。即 | 返回:bool ### 示例 ```tsl // 创建读写管道 sysExecNewPipe(0); path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; // 非阻塞执行,返回进程句柄 hand := sysExec(path, "tsl", nil, 0, code); // 获取SysExec进程所在管道的输出内容 t1 := ""; while t1="" do begin t1 := sysexecreadpipe(hand); sleep(100); // 100毫秒读取一次 end // 向SysExec进程所在管道写入内容 sysExecWritePipe(hand, "datetostr(today())\r\n"); sleep(500); // 等待写入的内容执行完成,也可写成上面的循环的方式获取 // 获取管道执行写入内容后的输出内容 t2 := sysexecreadpipe(hand); t3 := sysTerminate(code, hand); // 终止进程 return array(hand, t1, t2); // 输出:如下图: ``` ## `sysexecdeletepipe(process_handle)` 声明:function 删除指定进程的管道。参数缺省时,删除默认管道。 | 参数 | 类型 | 说明 | | ---------------- | ---- | -------------------------- | | `process_handle` | | 数值,可选参数,进程句柄。 | 返回:bool ### 示例 ```tsl // 创建读写管道 sysExecNewPipe(0); path := "D:\\Program Files\\Analyse.NET\\TSL.exe"; // 非阻塞执行,返回进程句柄 hand := sysExec(path, "tsl", nil, false, code); // 获取SysExec进程所在管道的输出内容 t1 := ""; while t1="" do begin t1 := sysexecreadpipe(hand); end de_ret := sysExecDeletePipe(hand); // 删除成功,尝试向指定进程所在管道写入内容 if de_ret then begin try sysExecWritePipe(hand, " datetostr(20221130T)\r\n"); return false; except // 写入失败,管道删除成功 return true; end; end sysTerminate(code, hand); // 终止进程 return false; // 输出: // 执行超时。 ``` ## `sysGetSubProcesses(pid)` 声明:function 获得进程的子进程列表 | 参数 | 类型 | 说明 | | ----- | ------- | -------------------------------------------------------------- | | `pid` | integer | 整数,可选参数,进程ID。未指定时默认获取当前进程内的子进程列表 | 返回:array,tablearray ### 示例 范例01:获取当前进程的子进程列表 ```tsl ret := sysGetSubProcesses(); if istabel(ret) then return ret; else return "获取进程的子进程列表失败!" ``` 范例02:获取指定进程的子进程列表 ```tsl // 打开记事本,在任务管理器中查找对应进程ID: ret := sysGetSubProcesses(2932); if istabel(ret) then return ret; else return "获取进程的子进程列表失败!" ``` ## `sysputenv(env_value)` 声明:function 设置当前运行环境的指定环境变量的值。 | 参数 | 类型 | 说明 | | ----------- | ------ | --------------------------- | | `env_value` | string | 字符串,环境变量名=变量值。 | 返回:integer ### 示例 ```tsl // 以笔者的电脑环境为例,来展示该函数的功能: // 如图所示,本地现有名为OS的环境变量: // 并且在powerShell等控制台中可以获取到: // 在TSL执行环境中,我们可以使用SysGetenv函数获取指定环境变量,如下: ``` 范例01:将原环境变量值替换为设置值。 ```tsl // 从下面的截图中,可以看出,SysPutenv只能设置当前TSL运行环境的环境变量。 // 在客户端中用代码实现如下: res := sysgetenv("OS"); // 获取本地原有环境变量OS的值 echo res; // 打印原有环境变量OS的值 ret := sysputenv("OS=Test"); // 更改当前运行环境的环境变量OS的值 if ret=0 then return sysgetenv("OS"); // 更改成功,获取更改后的环境变量OS的值 // 返回字符串“Test” ``` 范例02:将新增值添加到原有环境变量中 ```tsl // 在客户端中用代码实现如下: res := sysgetenv("OS"); // 获取本地原有环境变量OS的值 echo res; // 打印原有环境变量OS的值 res := "OS="$res$";Test"; // 原有环境变量与设置值拼接 ret := sysputenv(res); // 更改当前运行环境的环境变量OS的值 if ret=0 then return sysgetenv("OS"); // 更改成功,获取更改后的环境变量OS的值 // 输出:返回字符串" Windows_NT;Test" ``` ## `sysErrorMessage(code)` 声明:function 返回指定代码表示的系统错误信息。 | 参数 | 类型 | 说明 | | ------ | ------- | -------------- | | `code` | integer | 整数,提示代码 | 返回:string ### 示例 ```tsl return rdo2 sysErrorMessage(200); // 输出:代码段不可大于或等于 64K。 ``` ## `sysgetenv(name)` 声明:function 获取当前运行环境下指定环境变量的值。 | 参数 | 类型 | 说明 | | ------ | ------ | -------------------- | | `name` | string | 字符串,环境变量名。 | 返回:string ### 示例 ```tsl // 读取本地已有系统环境变量OS的值 return sysgetenv("OS"); // 返回字符串“Windows_NT” // 注:更具体的应用可参考Sysputenv中的范例。 ``` ## `sysWaitForMultipleObjects(objects, b_wait_all, wait_ms)` 声明:function 等待占有多个对象,例如互斥对象。支持windows和linux的进程 | 参数 | 类型 | 说明 | | ------------ | ---------------- | -------------------------------------------------------------------------- | | `objects` | array of integer | 一维数字数组,对象句柄数组 | | `b_wait_all` | bool | 真假,是否等待所有的对象。为真等待所有的,为假则仅需任意一个对象等待成功。 | | `wait_ms` | integer | 整数,等待的毫秒数,-1则为永远等待。 | 返回:integer ### 示例 ```tsl sysExecNewPipe(); // 创建管道 path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; do_s1 := array('C:\\TinySoftNG\\AnalyseNG.NET\\tsl.exe', 'C:\\DoTSL\\otherTest\\TestEnv.tsl'); do_s2 := array('C:\\TinySoftNG\\AnalyseNG.NET\\tsl.exe', 'C:\\DoTSL\\otherTest\\TestEcho.tsf'); // 创建一个被挂起的进程,两个会返回的进程 hand1 := sysExec(path, 'TSL', nil, array('wait': false, 'in': 'c := "333"\r\n'), code); hand2 := sysExec(path, do_s1, nil, false, code); hand3 := sysExec(path, do_s2, nil, false, code); r := sysWaitForMultipleObjects(array(hand1, hand2, hand3), 0, 10 * 1000); // 仅需任意一个对象等待成功 t := sysexecreadpipe(); // 读取管道内容 sysTerminate(code, hand1); // 终止进程 sysTerminate(code, hand2); // 终止进程 sysTerminate(code, hand3); // 终止进程 return array(r, t); 返回: 返回为1,说明hand1没有等待成功,而至少hand2是有等待成功了。注:其中的TestEnv.tsl与TestEcho.tsf实现分别如下:TestEnv.tsl: sleep(500);t := Sysgetenvs();echo "sys: ", tostn(t), '\r\n';return 1; test_echo.tsf: sleep(2 * 1000); // 停2秒echo 'TestEchoIN\r\n';return 1; ``` ## `sysCreateMutex(mutex_name)` 声明:function 创建一个互斥锁。 | 参数 | 类型 | 说明 | | ------------ | ------ | ------------------ | | `mutex_name` | string | 字符串,互斥锁名称 | 返回:integer ### 示例 ```tsl // 创建一个名称为tinysoft的互斥锁 ret := rdo2 sysCreateMutex("tinysoft"); return ret; // 输出:2632 ``` ## `sysProcessId()` 声明:function 获得运行的进程ID。 返回:integer ### 示例 ```tsl {获得天软客户端程序当前的进程ID,即在任务管理器中查看到的进程对应的PID。每个电脑的进程不一样} return rdo2 sysProcessId(); ``` ## `sysParamcount()` 声明:function 获得命令行参数个数。(不包括执行的自身.TSL参数) 返回:integer ### 示例 ```tsl // 本地test.tsl文件中代码如下: test(); function test(); begin // 获取命令行传入参数个数 echo sysParamcount(); end // 在cmd中打开文件所在文件夹,输入命令:tsl test.tsl 1 2 3 ``` ## `sysThreadId()` 声明:function 获得运行的线程ID。 返回:integer ### 示例 ```tsl // 获得天软客户端程序当前的进程运行的线程ID return rdo2 sysThreadId(); ``` ## `sysWaitForSingleObject(object, wait_ms)` 声明:function 等待占有一个对象,例如互斥对象。支持windows和linux的进程 | 参数 | 类型 | 说明 | | --------- | ------- | ------------------------------------ | | `object` | integer | 整数,对象名柄 | | `wait_ms` | integer | 整数,等待的毫秒数,-1则为永远等待。 | 返回:integer ### 示例 ```tsl sysExecNewPipe(); // 创建管道 path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; do_s := array('C:\\TinySoftNG\\AnalyseNG.NET\\tsl.exe', 'C:\\DoTSL\\otherTest\\TestEnv.tsl'); hand1 := sysExec(path, do_s, nil, array('wait': false, 'in': 'd := "123"\r\n'), code); r := sysWaitForSingleObject(hand1, 10 * 1000); // 等待线程的状态 t := sysexecreadpipe(); // 读取管道内容 return array(r, t); 返回: 其中,TestEnv.tsl文件的实现如下: // 当前sys的环境变量t := Sysgetenvs();echo "sys: ",tostn(t),'\r\n';s := Readln();//读取echo 'IN:',s,'\r\n';return 1; ``` ## `sysGetenvs()` 声明:function 获取当前运行环境的全部环境变量串。 返回:array of string ### 示例 ```tsl // 读取当前运行环境的所有环境变量 return sysGetenvs(); // 部分结果截图: ``` ## `sysexecGetenvs()` 声明:function 获取子进程的环境变量,应用于Sysexec创建的子进程。 返回:array of string ### 示例 ```tsl sysExecSetEnvs(array("test=test", "test1=test1"), 2); return sysexecGetenvs(); // 输出: // array("test=test","test1=test1","ALLUSERSPROFILE=C:\\ProgramData","APPDATA=C:\\Users\\cobia\\AppData\\Roaming","CODEX_CI=1","CODEX_MANAGED_BY_NPM=1","CODEX_MANAGED_PACKAGE_ROOT=... // 注:更多应用可参考Sysexecsetenvs ``` ## `dbglocalcancel(id)` 声明:function 注销任务。该功能可以用来终止运行的WEB任务。 | 参数 | 类型 | 说明 | | ---- | ------- | ----------------------------------------------------------------- | | `id` | integer | 为dbglocalrunning中返回信息中的id字段以十六进制模式转换为64位整数 | 返回:bool ## `sysThreadSelf()` 声明:function 获取当前程序的线程ID。 返回:integer|int64 ### 示例 ```tsl // 在客户端中,本地执行如下代码: return sysThreadSelf(); // 返回值:线程ID,如11000 // 通过cmd查看天软客户端进程与线程,结果如下: ``` ## `syslinuxkrnlclosemutex(name, isprivate)` 声明:function 支持在LINUX上手动删除掉因互斥支持产生的系统信号量以及临时目录的文件 | 参数 | 类型 | 说明 | | ----------- | ------ | ------------------ | | `name` | string | 字符串,互斥锁名称 | | `isprivate` | bool | 是否私有 | 返回:any ## `sysSetThreadPriority(pri, tid)` 声明:function 设置线程优先级 | 参数 | 类型 | 说明 | | ----- | ------- | ------------------------------------------------ | | `pri` | integer | 线程优先级 | | `tid` | integer | 可选参数,线程ID。未指定时默认设置当前线程优先级 | 返回:integer ### 示例 范例01:设置当前线程优先级 ```tsl ret := sysSetThreadPriority(1); if ret=0 then return 1; else return "设置线程优先级失败!"; // 输出:返回1,设置成功。 ``` 范例02:设置指定线程优先级 ```tsl // 创建函数指针 c := makeinstance(thisfunction(func_pos), "cdecl", 1); // 创建线程 handle := CreateThread(nil, 10240000, c, nil, 0, tid); ret := sysSetThreadPriority(1, tid); if ret=0 then return 1; else return "设置线程优先级失败!"; // 定义WindowsAPI的CreateThread函数声明。 function CreateThread(attr: pointer;size: pointer;addr: pointer;p: pointer;flag: integer;var threadid: integer): pointer;external "kernel32.dll" name "CreateThread"; // 自定义函数,用于创建函数指针 function FuncPos(p: pointer): integer; begin sleep(random(3000)); return 1; end; // 输出:返回1,设置成功。 ``` ## `sysGetThreadPriority(pri, tid)` 声明:function 获取线程优先级 | 参数 | 类型 | 说明 | | ----- | ------- | ------------------------------------------------------ | | `pri` | integer | 变参,整数,线程优先级 | | `tid` | integer | 整数,可选参数,线程ID。未指定时默认获取当前线程优先级 | 返回:integer ### 示例 范例01:获取当前线程优先级 ```tsl ret := sysGetThreadPriority(pri); if ret=0 then return pri; else return "获取线程优先级失败!"; ``` 范例02:获取指定线程优先级 ```tsl tid := 18024; // 指定线程ID ret := sysGetThreadPriority(pri, tid); if ret=0 then return pri; else return "获取线程优先级失败!"; ``` ## `sysGetThreadName(tid)` 声明:function 获取线程名称 | 参数 | 类型 | 说明 | | ----- | ------- | ---------------------------------------------------- | | `tid` | integer | 整数,可选参数,线程ID。未指定时默认获取当前线程名称 | 返回:string ### 示例 范例01:获取当前线程名称 ```tsl ret := sysGetThreadName(); if ret then return ret; else return "获取线程名称失败!"; ``` 范例02:获取指定线程名称 ```tsl tid := 18024; // 指定线程ID ret := sysGetThreadName(tid); if ret then return ret; else return "获取线程名称失败!"; ``` ## `sysGetThreads(pid)` 声明:function 获取进程内的线程列表 | 参数 | 类型 | 说明 | | ----- | ------- | ------------------------------------------------------------ | | `pid` | integer | 整数,可选参数,进程ID。未指定时默认获取当前进程内的线程列表 | 返回:array,tablearray ### 示例 范例01:获取当前进程内的线程列表 ```tsl ret := sysGetThreads(); return ret; // 输出: // array(52412,37192,19952,47976,46252,25228,13360,24792,33176) ``` 范例02:获取指定进程内的线程列表 ```tsl // 打开记事本,在任务管理器中查找对应进程ID: ret := sysGetThreads(2932); return ret; // 输出: // array() ``` ## `sysPPid(pid)` 声明:function 获得进程的父进程ID | 参数 | 类型 | 说明 | | ----- | ------- | ---------------------------------------------------------- | | `pid` | integer | 整数,可选参数,进程ID。未指定时默认获取当前进程的父进程ID | 返回:integer ### 示例 范例01:获取当前进程的父进程ID ```tsl ret := sysPPid(); if ret then return ret; else return "获取进程的父进程ID失败!"; ``` 范例02:获取指定进程的父进程ID ```tsl // 打开记事本,在任务管理器中查找对应进程ID: ret := sysPPid(28848); if ret then return ret; else return "获取进程的父进程ID失败!"; // 输出: // 无输出。 ``` ## `sysPidOfTid(tid)` 声明:function 获取线程所属进程ID | 参数 | 类型 | 说明 | | ----- | ------- | ------------ | | `tid` | integer | 整数,线程ID | 返回:integer ### 示例 范例01:获取当前线程所属进程 ```tsl tid := sysThreadId(); // 获取当前线程ID ret := sysPidOfTid(tid); if ret then return ret; else return "获取线程所属进程ID失败!" ``` ## `sysPidOfHandle(handle)` 声明:function 根据进程句柄获取进程ID。在Linux上,返回和进程句柄值相同的整数 | 参数 | 类型 | 说明 | | -------- | ------- | -------- | | `handle` | integer | 进程句柄 | 返回:integer ### 示例 范例01:根据进程句柄获取进程ID ```tsl // TSL解析器路径 path := "D:\\Program Files\\AnalyseNG.NET\\TSL.exe"; // 创建管道 ret := sysExecNewPipe(); // 创建一个TSL解析器进程 if ret then handle := sysExec(path, "TSL", nil, 0, code); // 返回进程句柄 ret := sysPidOfHandle(handle); sysTerminate(rc, handle); // 关闭TSL解析器进程 if ret then return ret; else return "根据进程句柄获取进程ID失败!" ``` ## `sysHandleOfPid(pid, rights, inherithandle)` 声明:function Windows上获取进程id对应的句柄,Linux上获取指定文件ID的复制ID。得到的句柄可用函数FAQ:SysCloseHandle进行关闭。 | 参数 | 类型 | 说明 | | --------------- | ------- | ----------------------------------------------------------------------- | | `pid` | integer | 整数,进程ID | | `rights` | integer | 整数,可选参数,设置进程句柄权限,Linux上无效。常见的权限设置值见下表。 | | `inherithandle` | integer | 布尔值,可选参数,是否继承,Linux上无效 | 常见权限值: | 值 | 十进制值 | 访问权限 | 可操作范围 | | -------- | -------- | ------------------------------------------- | ------------------------------------- | | `0x0010` | 16 | PROCESS_VM_READ | 读取进程内存内容 | | `0x0400` | 1024 | PROCESS_QUERY_INFORMATION | 查询完整进程信息(令牌、优先级等) | | `0x1000` | 4096 | PROCESS_QUERY_LIMITED_INFORMATION(缺省值) | 仅查询进程基础信息(PID、退出代码等) | | `0xFFFF` | 65535 | PROCESS_ALL_ACCESS | 所有权限(包括终止、内存写入等) | 返回:integer ## `sysGetLastError()` 声明:function 获得系统操作的最后一个返回代码。 返回:integer ## `sysCmdLine()` 声明:function 获得解析器的真实命令行串。 返回:string ## `sysTerminate(ret_code, handle)` 声明:function 终止进程。 | 参数 | 类型 | 说明 | | ---------- | ------- | ------------------------------------------ | | `ret_code` | integer | 整数,终止进程返回的代码。 | | `handle` | integer | 整数,终止进程的句柄。缺省为终止自身进程。 | 返回:any ## `sysCloseHandle(handle)` 声明:function 关闭一个句柄,如互斥锁,文件句柄等。 | 参数 | 类型 | 说明 | | -------- | ------- | -------------- | | `handle` | integer | 整数,句柄编号 | 返回:bool ### 示例 ```tsl // 启动windows平台下的windows命令处理程序,然后关闭启动该程序时返回的句柄 tool_path := "C:\\Program Files\\Windows Media Player"; ret := rdo2 sysExec(tool_path+"\\wmplayer.exe", "D:\\test1\\when_ever.mp3", tool_path, 1, returncode); ret1 := rdo2 sysCloseHandle(ret); return ret1; // 输出:1 ``` ## `dbglocalrunning()` 声明:function 获得当前所有的任务列表以及堆栈信息,主要用于web等检查在运行中的任务。 返回:array,tablearray ### 示例 ```tsl // 在本地脚本中运行下面代码: t := dbglocalrunning(); echo toStn(t); return 1; // 打印信息如下: array( ("StartInfo": ("id": "000001b9b8e30440", "info": "C:\\Users\\xxxxx\\Tinysoft\\Analyse.NET\\editer\\cmpCachesnewfile\\new12.tsl", "createtm": 45602.6995526042), "CallStack": ( ("NAME": "__main__", "USER": "local", "LINE": 3)))) ``` ## `sysGetProcessList()` 声明:function 获取当前进程列表信息 返回:array,tablearray ### 示例 ```tsl ret := sysGetProcessList(); if ret<>0 then return ret; else return "当前进程列表信息失败!"; // 部分结果如下: ``` ## `sysGetProcessListw()` 声明:function 获取当前进程列表信息,信息中字符串为宽字节字符串 返回:array,tablearray ### 示例 ```tsl ret := sysGetProcessListw(); if ret<>0 then return ret; else return "当前进程列表信息失败!"; // 部分结果如下: ``` ## `sysGetWndOfCaption(cap, is_contain_string)` 声明:function 获得所有标题窗口串包含或者等于指定串的所有窗口句柄。 | 参数 | 类型 | 说明 | | ------------------- | ------ | ---------------------------------------------- | | `cap` | string | 字符串,窗口的标题。 | | `is_contain_string` | | 布尔类型,是否包含,可选参数参数,默认是包含。 | 返回:array of hwnd ### 示例 ```tsl // 获取标题是”test.docx”的窗口句柄。 v := sysGetWndOfCaption("test.docx"); echo v; ``` ## `sysGetPidtidOfWnd(wnd, thread_id)` 声明:function 获得窗口句柄的进程ID, 通过ThreadId可输出线程id | 参数 | 类型 | 说明 | | ----------- | ------- | ------------------------------------------------ | | `wnd` | hwnd | 整型,窗口句柄。 | | `thread_id` | integer | 输出值,整型,线程号,给定该参数可以获取线程ID。 | 返回:integer ### 示例 ```tsl // 获取标题是”test.docx”的窗口的word的进程ID。 // 获取标题是”test.docx”的窗口句柄 wnd := sysGetWndOfCaption("test.docx"); // 通过窗口句柄获得进程ID v := sysGetPidtidOfWnd(wnd[0]); echo v; ``` ## `sysSetThreadName(name, tid)` 声明:function 设置线程名称 | 参数 | 类型 | 说明 | | ------ | ------- | ---------------------------------------------------- | | `name` | string | 字符串,要设置的名称 | | `tid` | integer | 整数,可选参数,线程ID。未指定时默认设置当前线程名称 | 返回:integer ### 示例 范例01:设置当前线程名称 ```tsl ret := sysSetThreadName("TinySoft"); if ret=0 then return 1; else return "设置线程名称失败!"; // 输出:返回1,设置成功。 ``` 范例02:设置指定线程名称 ```tsl // 创建函数指针 c := makeinstance(thisfunction(func_pos), "cdecl", 1); // 创建线程 handle := CreateThread(nil, 10240000, c, nil, 0, tid); ret := sysSetThreadName("TinySoft", tid); if ret=0 then return 1; else return "设置线程名称失败!"; // 定义WindowsAPI的CreateThread函数声明。 function CreateThread(attr: pointer;size: pointer;addr: pointer;p: pointer;flag: integer;var threadid: integer): pointer;external "kernel32.dll" name "CreateThread"; // 自定义函数,用于创建函数指针 function FuncPos(p: pointer): integer; begin sleep(random(3000)); return 1; end; // 输出:返回1,设置成功。 ```