#### 资源访问函数 ##### 内容 - 资源访问函数简介 - 数据库访问函数 - 文件访问函数 - 网络访问以及相关函数 - INI文件处理函数 - 进程相关函数 - 本地资源相关函数 ##### 资源访问函数简介 资源访问函数一般仅为TSL本地解析器所支持,例如CGI,WORD模板的TSL语句以及其他本地TSL语言解析器。 对于服务器运算的金融分析.NET,由于资源访问函数基本上都需要访问到服务器上的一些特有资源,例如文件访问,数据库访问等,而因为服务器上的数据库以及文件的保密性,这些函数在一般情况不为在线版本的用户开放,仅仅只有当用户购买了服务器版本,由系统管理员在服务器上为用户开放了之后才可以使用。 ##### 数据库访问函数 ###### 内容 - ExecSQL - SQLBeginTrans - SQLInTrans - SQLCommit - SQLRollBack - SQLErrorMsg - SQLCloseConn - 数据库配置 - Openforwardonly模式 ###### ExecSQL 用途:数据库访问函数相关函数。 参数:arg1,arg2,arg3,arg4(按示例顺序传入)。 返回:处理后的结果值。 范例 范例01:同时返回结果集与字段结构信息,并将字段转换为大写(以MySQL为例) ```tsl f31 := 0; // 不缓存 f30 := 0x40000000; // 不访问元数据 f29 := 0x20000000; // 转为大写 f28 := 0x10000000; // 转大小写有效 df := 2; // 同时返回结果集与字段结构信息 Flags := f31 + f30 + f29 + f28 + df; echo Flags; echo 'FLAGS高四位:', Flags .& 0x80000000 <> 0, Flags .& 0x40000000 <> 0, Flags .& 0x20000000 <> 0, Flags .& 0x10000000 <> 0; echo 'FLAGS低位值:', Flags .& 3; // test表中数据为浦发银行2023-8-31至2023-9-13的收盘价 sqlstr := 'select * from test where close<(select avg(close) from test)'; ret := rdo2 ExecSQL(Flags, 'mysql', sqlstr, result); if ret then return result; else return rdo2 SQLErrorMsg(); // 报错信息 ``` 其中, Result[0]返回结果: Result[1]返回字段结构信息: 范例2: ```tsl // 表名:SZ000002cy_5m // 数据库别名:cfsql (SQL和天软交互时配置的数据库别名) s := "select * from SZ000002cy_15m;"; ret := rdo2 ExecSQL("cfsql", s, data); if ret then return data; ``` 范例03:存贮过程的调用,参数名TestParamName是一个输入输出参数,最后param的结果会被修改。 ```tsl param := array("TestParamName":("Value":"ParamNameValue", "Direction":3)); ExecSQL(param, "test", "myStoredProctest", result); ``` Sys_refcursor输出参数: API链接方式支持oracle存贮过程的sys_refcursor输出参数,会作为多结果集返回。 假定oracle存贮过程如下: create or replace procedure testproc(b out sys_refcursor,c out sys_refcursor) is begin open b for select \* from TESTTABLE; open c for select \* from TESTTABLE; end testproc; 可以使用如下代码来获得两个结果集: a:=array( "b":("Direction":2,"Type":22), "c":("Direction":2,"Type":22) ); execsql(a,"ora2","TESTPROC",r); 注:ADO模式无法支持此种类型返回参数。 范例04:Array DML 方式批量插入数据范例 ```tsl // 获取数据模型 r := TSFL_SQL_GetData(20130101T, 20131231T); {Insert语句,注意下列数据中EndDate,StockID,StockName,price,vol是占位符,对应param数组中的占位符。与数据库表中列名无关,此处没有指定Test的列名,按照数据库表中列的顺序给定数据。如需指定列名,在Test后带上列名} s := "insert into Test values(:EndDate,:StockID,:StockName,:price,:vol)"; {插入数据列值:EndDate,StockID,StockName,price,vol是占位符, } param := array("EndDate":array("Direction":1, "Value":r[:, 'EndDate']), "StockID":array("Direction":1, "Value":r[:, 'StockId']), "StockName":array("Direction":1, "Value":r[:, 'StockName']), "price":array("Direction":1, "Value":r[:, 'Close']), "vol":array("Direction":1, "Value":r[:, 'Vol'])); // 执行SQL操作 ret := rdo2 ExecSQL(param, 'SQLAlias', s, result); return result; ``` 范例05:输出转为WideString类型 ```tsl SQLStr1 := "select * from test"; // 数据库别名使用widestring宽字节 DBname := L'pgsql'; ExecSQL(DBname, SQLStr1, t); echo tostn(t); return t; ``` 源串中字符串为宽字节: 更多关于数据库的详细说明及范例,见专题: http://www.tinysoft.com.cn/tsdn/helpdoc/index.tsl?itemid=15106 ###### SQLBeginTrans ###### SQLInTrans ###### SQLCommit ###### SQLRollBack ###### SQLErrorMsg ###### SQLCloseConn ###### 数据库配置 数据库配置主要分本地配置和服务器配置两种方式。本地配置主要用于本地的文件或共享给本地的文件的交互,服务器配置主要用于对服务器端的文件或者共享给服务器的文件的交互。一般用户只需要在本地配置即可。 ####### 内容 - 配置说明 ####### 配置说明 | 项目 | 本地配置 | 服务器配置 | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | | 交互对象 | 本地文件,本地共享文件 | 服务器文件,服务器共享文件 | | 调用函数或类 SQL 方式 | 在模型前加关键字 rdo2 | 直接调用,不加 rdo2 | | 配置文件 | 安装目录下,如 `C:\\Program Files\\Tinysoft\\Analyse.NET\\Plugin\\execsql.ini` | 服务器目录下所有 bin,如 `D:\\Tinysoft\\bin\\plugin\\execsql.ini` | | 配置程序 | 与 execsql.ini 同目录下的 ConnectMan.exe,执行后继续下面的选择 | 同左 | | 提供程序 | 选择与数据库匹配的 | 同左 | | 服务器名称 | 本地服务器可用 127.0.0.1/localhost,其他输入服务器名 | 同左 | | 用户名 | 用户登录数据库的用户名 | 同左 | | 密码 | 用户登录数据库的密码 | 同左 | | 空白密码 | 不勾选 | 同左 | | 允许保存密码 | 勾选 | 同左 | | 数据库 | 选择需要操作的数据库 | 同左 | | 测试连接 | 连接成功 | 同左 | | 复制连接串 | `Provider=SQLOLEDB.1;Password=testpw;Persist Security Info=True;User ID=testusername;Initial Catalog=test;Data Source=THINKPAD`
说明:该语句不能换行 | 同左 | | Execsql.ini 完整配置 | `[test]`
`ConnectStr=Provider=SQLOLEDB.1;Password=testpw;Persist Security Info=True;User ID=testusername;Initial Catalog=test;Data Source=THINKPAD`
`permit=local`
说明:`test` 为数据库别名;`ConnectStr` 为连接字符串;`Permit` 为提交用户,local 表示本地客户端登录用户 | 同左 | ###### Openforwardonly模式 在不需要对已访问过的数据进行再次访问时,设置openforwardonly游标模式,可以减少数据库访问的中间结果集对内存的开销,大数量级的数据访问中可以有效地提高交互性能。 ####### 内容 - TS-SQL语句中设置Openforwardonly模式 - ExecSQL函数中设置Openforwardonly模式 ####### TS-SQL语句中设置Openforwardonly模式 在TS-SQL语法中,可以通过设置selectopt为0x8000000的方式来指定Openforwardonly模式。 如: Return Select selectopt(0x8000000) _ from sqltable 'select _ from TSP_AccountTradeDetails where Action=10' of TSP_GetAlias() end; 则表示从数据库中提取TSP_AccountTradeDetails的部分数据时,游标开启只进模式,提取到结果集后,不再对该结果集进行缓存。 ####### ExecSQL函数中设置Openforwardonly模式 ######## 内容 - 第一种:当前交互语句设置为Openforwardonly模式 - 第二种:设置当前环境缺省为Openforwardonly模式 ######## 第一种:当前交互语句设置为Openforwardonly模式 通过设置Flags参数的第27位为真(即0x8000000)生效。 SQLStr:="select \* from Test where EndDate>='2013-06-30'"; Flags:=0x8000000; //选择Openforwardonly模式 Ret:=rdo2 ExecSQL(Flags,'SQLAlias',SQLStr,t); if ret then return result; else return rdo2 SQLErrorMsg();//报错信息 例如:执行下列SQL语句时,服务器端不会缓存该语句访问的结果集。 ######## 第二种:设置当前环境缺省为Openforwardonly模式 在ExecSQL的方式中,还可以通过配置改变当前交互环境的默认方式为Openforwardonly模式。 支持配置ExecSql交互的缺省方式与指定数据库交互的缺省方式。 当配置为Openforwardonly模式后,可以通过指定设置Flags参数的第26位为真(即0x4000000)来取消,即临时指定为Notopenforwardonly模式。 配置方法: [ExecSql Config] ExecSqlForwardOnly=1 ########设置此处则,默认任何别名在EXECSQL均启用openforwardonly模式 [DBAlias] ExecSqlForwardOnly=1 ########设置此处则,默认数据库别名DBAlias在EXECSQL均启用openforwardonly模式在天软安装目录下的plugin\ExecSql.ini文件中,添加以下配置 注:以上缺省方式的设置仅支持ExecSql的操作,不支持TS-SQL语句。 SQLStr:="select \* from Test where EndDate>='2013-06-30'"; Ret:=rdo2 ExecSQL('SQLAlias',SQLStr,t); if ret then return result; else return rdo2 SQLErrorMsg();//报错信息使用范例:在配置了上述缺省方式之后,操作如下 即,由于ExecSQL执行的当前环境缺省为Openforwardonly模式,所以默认情况下上述执行的sql语句不会缓存结果集。 SQLStr:="select \* from Test where EndDate>='2013-06-30'"; Flags:=0x4000000; //指定为Notopenforwardonly模式 Ret:=rdo2 ExecSQL(Flags,'SQLAlias',SQLStr,t); if ret then return result; else return rdo2 SQLErrorMsg();//报错信息 在这种环境下,当提取的某次结果集,在后面的过程中还需要被再次或多次访问时,我们又希望它能够被缓存,来提高访问效率,此时,我们可以在本次执行的ExecSQL操作中进行单次取消Openforwardonly模式,进入Notopenforwardonly模式进行执行,例如: ##### 文件访问函数 ###### 内容 - FileList - FileAge - RemoveDir - FileSize - SetFileAttr - FileDelete - Sysdbfwrite - FileTime - SetFileAge - WriteFile - WriteToLog - FileExists - 目录别名 - FileCopy - SetFileTime - ReadExcelSheets - CreateDir - FileAttr - ReadFile - Sysdbfread - FileRename - ImportFile - ExportFile - 导入导出类型函数 - 文件读写类型函数 - ExportFile2 - ImportFile2 - FileMode - SetFileMode - FileAttrToStr - FileModeToStr - StrToFileAttr - StrToFileMode - Filemove ###### FileList 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 本地文件:C:\test11.txt ret := rdo2 FileList("", "c:\\test11.txt"); return ret; ``` ###### FileAge 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 本地文件:C:\test11.txt ret := rdo2 FileAge("", "c:\\test11.txt"); return FileDateToDateTime(ret); // 返回41153 ,日期2012-09-01 ``` ###### RemoveDir 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 本地文件夹:C:\test ret := rdo2 RemoveDir("", "c:\\test"); return ret; // 结果:1 ``` ###### FileSize 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 读取本地文件大小:C:\test11.txt ret := rdo2 FileSize("", "c:\\test11.txt"); return ret; // 结果:253 ``` ###### SetFileAttr 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 将本地文件c:\test11.tst设置为‘只读’文件 ret := rdo2 SetFileAttr("", "c:\\test11.txt", 1); return ret; // 结果:0 ,设置成功,可右键文件查看属性 ``` ###### FileDelete 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 本地文件:C:\test22.txt ret := rdo2 FileDelete("", "c:\\test22.txt"); return ret; // 结果:1 ``` ###### Sysdbfwrite 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:将数据导为dbf文件,各列数据类型自动判别。 ```tsl t := `array('A':(1, 1, 1), 'B':('a', 'b', 'c')); return rdo2 Sysdbfwrite('', ' D:\\testdbf.dbf ', t); // 导出的数据结果: ``` 范例02:将数据导为dbf文件,按指定数据结构定义。 ```tsl t := `array('A':(1, 1, 1), 'B':('a', 'b', 'c')); c := array("A":("Type":"C", "Width":10, "Dec":0), "B":("Type":"C", "Width":18, "Dec":0)); return rdo2 Sysdbfwrite('', ' D:\\testdbf.dbf ', t, c); // 在结构定义c中,将第A列的值数据类型导出为字符串,而非原数据的整型。 // 导出的数据结果(A列为字符串类型): ``` ###### FileTime 用途:日期时间处理函数。 参数: 返回:日期或时间值。 范例 ```tsl // 读取本地文件更新时间:C:\test11.txt ret := rdo2 FileTime("", "c:\\test11.txt"); return datetimetostr(ret); ``` ###### SetFileAge 用途:文件访问函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl // 本地文件:C:\test11.txt ret := rdo2 SetFileAge("", "c:\\test11.txt", DateTimeToFileDate(strtodatetime("2012-09-01 14:00:00"))); return ret; // 返回:0 (文件时间设置成功) ``` ###### WriteFile 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 写入一个二维字符数组 a := array(("aa", 21, "beijing"), ("bb", 22, "beijing"), ("vv", 23, "beijing"), ("ff", 24, "beijing"), ("ww", 25, "beijing") ); ret := rdo2 WriteFile(rwobj(), "", "c:\\test11.txt", 0, 1000, a); return ret; // 结果:1 (表示数据写入成功) ``` ###### WriteToLog 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl retun WriteToLog('测试', 'testlocal', '成功'); // 结果:在虚拟目录’testlocal’下生成了名为’测试2018-09-07.log’的txt文件,内容为’ 16:34:12->成功’。 ``` ###### FileExists 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl ret := rdo2 FileExists("", "c:\\test11.txt"); return ret; // 结果:1 (表示文件存在) ``` ###### 目录别名 目录别名是在服务器上定义好的字符串,该字符串会对照到服务器上一个指定的目录,该目录的读写权限是由服务器设置的。用户使用这个目录别名可以理解为某个服务器上指定的目录。 与本地的文件进行交互,用户需在调用函数前加关键字 rdo2。 ###### FileCopy 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 本地文件:C:\test11.txt,且不存在文件:C:\test123.txt ret := rdo2 FileCopy("", "c:\\test11.txt", "", "c:\\test123.txt", 1); return ret; // 结果:1 ``` ###### SetFileTime 用途:日期时间处理函数。 参数: 返回:日期或时间值。 范例 ```tsl // 本地文件:C:\test11.txt ret := rdo2 SetFileTime("", "c:\\test11.txt", DateTimeToFileDate(strtodatetime("2012-09-01 13:00:01"))); return ret; // 返回:0 (文件时间设置成功) ``` ###### ReadExcelSheets 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 读取本地文件的sheet列表名 rdo2 ReadExcelSheets('', 'd:\\test\\test.xls', r, 0); return r; // 结果:array("Sheet1","Sheet2","Sheet3") ``` 参考文件访问函数 ###### CreateDir 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 创建本地目录:C:\test ret := rdo2 CreateDir("", "c:\\test"); return ret; // 结果:1 ``` ###### FileAttr 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 本地文件:C:\test11.txt ret := rdo2 FileAttr("", "c:\\test11.txt"); return ret; // 结果:16 ``` ###### ReadFile 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 按原始类型读出文件的数据 size := rdo2 filesize("", "c:\\test.txt"); // 获取文件大小 ret := rdo2 ReadFile(rwraw(), "", "c:\\test.txt", 0, size, data); if ret then return data; ``` ###### Sysdbfread 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:读取本地文件testdbf.dbf的内容 ```tsl ret := rdo2 Sysdbfread("", "D:\\testdbf.dbf", t); if ret then return t; else return ‘读取本地数据失败’; // 若ret为1 (表示读取成功,此时读取的D:\\testdbf.dbf的数据存在变量t中) // 返回结果: A B 1 a 1 b 1 c ``` 范例02://读取本地文件testdbf.dbf的结构定义 ```tsl ret := rdo2 Sysdbfread("", "D:\\testdbf.dbf", t, 1); if ret then return t; else return ‘读取本地数据失败’; // 若ret为1 (表示读取成功,此时读取的结构定义存在变量t中) // 返回结果: type Width Dec A N 10 0 B C 18 0 ``` ###### FileRename 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 本地文件:C:\test11.txt ret := rdo2 FileRename("", "c:\\test11.txt", "c:\\test12.txt"); return ret; // 结果:1 ``` 差异说明当重命名的名称与本地文件同名时,windows下表现为重命名操作失败,而Linux中表现为直接覆盖已存在的同名文件,该差异由操作系统行为不同导致。 所以,在Linux中,最好先检测是否存在同名文件,再做重命名操作。 如若需要处理成:当指定路径下已存在该文件时,重命名操作失败。 则其实现可参考如下: ```tsl // 原文件路径与名称 snFilePath := "/home/tinysoft/newFile.txt"; // 重命名文件路径与名称 rFilePath := "/home/tinysoft/rawFile.txt"; if FileExists(rFilePath) then return 0; // 若新名称文件已存在,则返回0 r := FileRename('', rFilePath, snFilePath); return r; ``` ###### ImportFile 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01: ```tsl Data1 := rand(10, 5); ret1 := rdo2 exportfile(ftxls(), "", "c:\\test.xls", data1); if ret1 then begin ret2 := rdo2 ImportFile(ftxls(), "", "c:\\test.xls", data2); if ret2 then return data2; else return "导出失败"; end else return 0; ``` 范例02: ```tsl // 导入excel中的INF及NAN ret := rdo2 ImportFile(ftXLS(), '', 'C:\\testdata.xlsx', data); if ret then return Data; else return ret; ``` Excel中的数据: 导入到天软中的数据: 范例03: ```tsl // .xls文件与.xlsx 文件行列最大限制不一样,xls文件最大256列,.xlsx文件最大限制16384 // 列,此处有数据16000列的.xlsx文件,后缀名改为.xls文件,仍可以导入16000列,说明//该函数可以自动识别.xls或者.xlsx的文件格式 ret := rdo2 ImportFile(ftXLS(), '', 'C:\\testdata4.xls', data); if ret then return Data; else return ret; ``` 结果 范例04:导入csv文件 ```tsl LJ := "D:\\Test\\20241204.csv"; r := rdo2 ImportFile(ftcsv(), "", LJ, t); return t; ``` ###### ExportFile 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01: ```tsl data := rand(10, 5); ret := rdo2 ExportFile(ftxls(), "", "c:\\test.xls", data); if ret then return 1; else return 0; // 结果:1 (表示数据导出成功,可以在c盘看到test.xls文件) ``` 范例02: ```tsl // 导入excel中的INF及NAN data := `array('a':(1, 2, 3), 'b':array(4, 5, 6), 'c':array(1 / 0, 0.0 / 0.0, 0)); ret := rdo2 ExportFile(ftXLS(), '', 'C:\\testdata2.xlsx', data); if ret then return Data; else return ret; ``` 结果 天软数据: 导出到Excel中的数据: 范例03:导出数据为csv格式 ```tsl t := rand(10, array("A", "B", "C")); LJ := "D:\\Test\\20241204.csv"; r := rdo2 ExportFile(ftcsv(), "", LJ, t); return r; ``` ###### 导入导出类型函数 导入导出类型函数决定导入导出的文件类型。目前支持有逗号分割文件,EXCEL电子表格文件,天软对象流文件,天软对象字符串文件。这些函数用于ExportFile,ImportFile的Type参数。 ####### 内容 - ftCSV - ftXLS - ftXls2 - ftXls3 - ftStream - ftString - ftXML - ftdbf ####### ftCSV 参考导入导出类型函数 ####### ftXLS 参考导入导出类型函数 ####### ftXls2 参考导入导出类型函数 ####### ftXls3 参考导入导出类型函数 ####### ftStream 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例(t): 导出操作: ```tsl data := rand(10, array("A", "B", "C")); r := rdo2 Exportfile(ftStream(), '', 'E:\\test\\tsdata.stm', data); if r = 1 then return "导出成功"; else return r; // 导出失败 ``` 导入操作: ```tsl r := rdo2 Importfile(ftStream(), '', 'E:\\test\\tsdata.stm', data); if r = 1 then return data; else return r; // 导出失败 ``` 参考导入导出类型函数 ####### ftString 参考导入导出类型函数 ####### ftXML 参考导入导出类型函数 差异说明Linux中,暂不支持导入导出该文件类型 ####### ftdbf 参考导入导出类型函数 ###### 文件读写类型函数 文件读写类型函数是决定用户在调用文件读写函数的时候,读出或者写入的数据类型。这些文件读写类型函数用于ReadFile,WriteFile的DataType参数。 ####### 内容 - rwByte - rwInt - rwReal - rwStr - rwObj - rwRaw - rwBinary ####### rwByte 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl size := rdo2 filesize("", "c:\\test.txt"); // 获取文件大小 ret := rdo2 readFile(rwByte(), "", "c:\\test.txt", 0, size, data); ret := rdo2 readFile(rwraw(), "", "c:\\test.txt", 0, size, data1); if ret then return data1; ``` 参考文件读写类型函数 ####### rwInt 参考文件读写类型函数 ####### rwReal 参考文件读写类型函数 ####### rwStr 参考文件读写类型函数 ####### rwObj 参考文件读写类型函数 ####### rwRaw 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例(t): 写出到本地txt文件中 ```tsl str := 'Hello demo!!'; r := rdo2 WriteFile(rwraw(), '', "d:\\test.txt", -1, length(str), str); if r = 1 then return "写出成功"; else return r; ``` 读取本地txt文件内容 ```tsl r := rdo2 ReadFile(rwraw(), '', 'd:\\test.txt', 0, 10000, data); if r = 1 then return data; else return r; // 读取失败 ``` 参考文件读写类型函数 ####### rwBinary 参考文件读写类型函数 ###### ExportFile2 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 导出10\*5全1矩阵,到C:\\test.xlsx 文件的Sheet3,C2单元格。 ```tsl data := ones(10, 5); ret := rdo2 ExportFile2(ftxls(), "", "C:\\test.xlsx", data, 1, 0, "Sheet3", "C2"); return ret; // 结果:1 (表示数据导出成功,可以在c盘看到test.xlsx文件) ``` ###### ImportFile2 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 导入"C:\\test.xlsx"文件中的Sheet3的"C2:E5"数据,包含字段名称。 ```tsl ret := rdo2 ImportFile2(ftxls(), "", "C:\\test.xlsx", data, 1, 0, 0, "Sheet3", "C2:E5"); if ret then return data; else return "导入失败"; ``` Excel的数据: ###### FileMode 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 本地文件:C:\test11.txt ret := rdo2 FileMode("", "c:\\test11.txt"); return ret; // 结果:32 ``` ###### SetFileMode 用途:文件访问函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 将本地文件c:\test11.tst设置为‘只读’文件 ret := rdo2 SetFileMode("", "c:\\test11.txt", 1); return ret; // 结果:0 ,设置成功,可右键文件查看属性 ``` ###### FileAttrToStr 用途:将输入值转换为字符串。 参数: 返回:字符串。 范例 ```tsl // 本地存在备份文件c:\test11.txt attr := rdo2 FileAttr("", "c:\\test11.txt"); ret := rdo2 FileAttrToStr(attr); return ret; // 结果:”A” ``` ###### FileModeToStr 用途:将输入值转换为字符串。 参数: 返回:字符串。 范例 ```tsl // 本地存在备份文件c:\test11.txt attr := rdo2 FileMode("", "c:\\test11.txt"); ret := rdo2 FileModeToStr(attr); return ret; // 结果:” A” ``` ###### StrToFileAttr 用途:将字符串转换为对应类型。 参数: 返回:转换后的数值或日期。 范例 ```tsl Str1 := "A"; return rdo2 StrToFileAttr(Str1); // 结果:32 ``` ###### StrToFileMode 用途:将字符串转换为对应类型。 参数: 返回:转换后的数值或日期。 范例 ```tsl Str1 := "A"; return rdo2 StrToFileMode(Str1); // 结果:32 ``` ###### Filemove 用途:移动文件,支持跨卷移动(相比 FileRename 可跨盘)。 参数: 返回:成功返回 1,失败返回 0。 范例 范例01:同盘移动 ```tsl LJ0 := "E:\\test\\testdat3.xlsx"; // 源文件路径及文件名 LJ1 := "E:\\TestExcel\\testdat4.xlsx"; // 目标路径及文件名 r := rdo2 Filemove("", Lj0, "", LJ1); return r; ``` 返回1则移动成功,返回0则移动失败 范例02:跨盘移动 ```tsl LJ0 := "E:\\test\\TestB2.txt"; // 源文件路径及文件名 LJ1 := "C:\\test\\TestB.txt"; // 目标路径及文件名 r := rdo2 Filemove("", Lj0, "", LJ1, 2); return r; ``` 返回1则移动成功,返回0则移动失败 注:若移动失败,可先确认以下几点: 1、指定的目标路径是否存在 2、目标文件中是否存在同名文件而移动模式没有选择替换模式。 3、目标文件是否跨盘,而移动模式没有选择复制模式。 ##### 网络访问以及相关函数 ###### 内容 - GetHttp - PostHttp - InternetRequest - ParseHtml - GetURL - CreateHttpSession - SetHttpMode - SetHttpCallBack - GetHttpContent - GetHttpResponseHeader - SysSendMail ###### GetHttp 用途:网络访问以及相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例一: ```tsl // 访问tinysoft主页 ret := rdo2 GetHttp("http://tinysoft.com.cn", 500, data, code); if ret then return array(ret, data, code); else return "获取失败"; ``` 范例二:使用微软库进行连接 ```tsl // 访问tinysoft主页 ret := rdo2 GetHttp(0, "http://tinysoft.com.cn", 500, data, code); if ret then return array(ret, data, code); else return "获取失败"; ``` 范例三:使用TCP直接连接 ```tsl // 访问tinysoft主页 ret := rdo2 GetHttp(1, "http://tinysoft.com.cn", 500, data, code); if ret then return array(ret, data, code); else return "获取失败"; ``` ###### PostHttp 用途:网络访问以及相关函数相关函数。 参数: 返回:整数。 范例 范例一:获取指定网页内容 ```tsl // 访问tinysoft主页 ret := rdo2 PostHttp("http://tinysoft.com.cn", "Hello", 500, data, code); if ret then return array(ret, data, code); else return "获取失败"; ``` 范例二:使用微软库进行连接 ```tsl // 访问tinysoft主页 ret := rdo2 PostHttp(0, "http://tinysoft.com.cn", "Hello", 500, data, code); if ret then return array(ret, data, code); else return "获取失败"; ``` 范例三:使用TCP直接连接 ```tsl // 访问tinysoft主页 ret := rdo2 PostHttp(1, "http://tinysoft.com.cn", "Hello", 500, data, code); if ret then return array(ret, data, code); else return "获取失败"; ``` ###### InternetRequest ###### ParseHtml ###### GetURL 用途:网络访问以及相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```text GetURL('http://www.tinysoft.com.cn','index.html') //结果为:http://www.tinysoft.com.cn/index.html ``` ###### CreateHttpSession - GetHttp - PostHttp - InternetRequest - ParseHtml - GetURL - CreateHttpSession - SetHttpMode - SetHttpCallBack - GetHttpContent - GetHttpResponseHeader - SysSendMail ###### SetHttpMode 用途:网络访问以及相关函数相关函数。 参数: 返回:处理后的结果值。 范例 多段模式下获取指定网址中的内容,实时吐词方式 ```tsl sid := createhttpsession(); SetHttpMode(sid, 1); // 分段模式 url := " http://www.baidu.com"; r := GetHttp(url, 60000, v, code); echo "\r\ndone->", r, '->', code, '->', length(v), "\r\n"; echo v; // 分段未结束时GetHttp返回值为1,code值为1000 while r and code = 1000 do begin r := GetHttp(url, 60000, v, code); echo v; end; if r <> 1 then return "网页访问失败"; return code; ``` 实时打印显示:(分段未结束时code=200) ###### SetHttpCallBack 用途:网络访问以及相关函数相关函数。 参数: 返回:处理后的结果值。 回调函数说明: 进度(progress)回调模式的回调函数定义为: | 定义 | function progresscallback(session,TotalDown,Downloaded,TotalUpload,Uploaded); | | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 参数 | Session:session ID
TotalDown:整型,下载总字节数
Downloaded:整型,已下载总字节数
TotalUpload:整型,上传总字节数
Uploaded:整型,已上传总计字节数 | | 说明 | 进度回调过程中,下载总字节数,已下载总字节数,上传总字节数,已上传总计字节数等不一定在每一次回调都会变化,
因为会间隔一段时间进行进度更新,即便没有发生进度变化。 | | 返回 | 回调函数的返回值为0表示继续,如果返回为非0则结束请求。若提前结束请求时,此时GETHTTP等函数的返回值与code值为0 | header模式的回调函数定义为: | 定义 | function headercallback(session,headerline); | | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | 参数 | Session:session ID
headerline:字符串,当前行内容 | | 说明 | 获取头部信息。HEADERLINE是每来一行的内容,HEADER的结束是获得一个独立的回车换行。 | | 返回 | 回调函数的返回值为0表示继续,非0则结束请求。如果仅仅只需要取完HEADER即可,可以当headerline为回车换行时返回-1即可。若提前结束请求时,此时GETHTTP等函数的返回值与code值为0 | 范例 下载过程中通过进度回调获取实时下载进度,通过头部回调获取头部信息 ```tsl sid := createhttpsession(); SetHttpCallBack(sid, findfunction("DownProg")); // 进度回调 SetHttpCallBack(sid, findfunction("head"), "header"); // 头部回调 s := "http://www.baidu.com"; // 小型下载 m := "http://www.tinysoft.com/download/setup64.exe"; // 具备下载总量的下载 l := "http://speed.cloudflare.com/__down?bytes=123456789"; // 头部没有content-length的下载 r := GetHttp(s, 60000, v, code); // 可以用s/m/l看看区别 echo "\r\n=>done ", r, '->', code, '->', length(v), "\r\n"; return 1; // 进度回调函数 function DownProg(sid, AlldnB, dnB, AllupB, upB); // progresscallback begin if dnB > 0 then//如果已开始下载则打印 begin R := AlldnB > 0?dnB / AlldnB * 100:0; S := "->" + DupeString(#8, Ceil(R / 10)); echo S, int(R), "% ", dnB$"/", AlldnB, "\r\n"; end; return 0; // 请求继续,返回其它,如return 1;则表示请求到此处就结束 end; // 头部回调模型 function head(sid, hline); begin echo hline; // if hline="\r\n" then //return -1; // 如果返回header后就结束请求打开这两行即可 return 0; // 请求继续 end; ``` 打印效果: ###### GetHttpContent 用途:网络访问以及相关函数相关函数。 参数: 返回:处理后的结果值。 范例 下载过程中,一边下载一边导出到本地 ```tsl sid := createhttpsession(); sethttpcallback(sid, findfunction("DownProg")); // 进度回调 s := "http://www.baidu.com"; // 小型下载 GetHttp(s, 60000, v, code); echo "\r\n---->done", '->', code, '->', length(v); return 1; // 进度回调函数 function DownProg(sid, AlldnB, dnB, AllupB, upB); // progresscallback begin if dnB > 0 then//如果已开始下载则保存到本地 begin if dnB > sysparams["__DownProg_dnB"] then begin hc := GetHttpContent(sid); // 获取当前内容 ret := WriteFile(rwRaw(), '', "E:\\test\\log_Data.txt", 0, Length(hc), hc); end; sysparams["__DownProg_dnB"] := dnB; echo "->", dnB$"/", AlldnB, "\r\n"; end; return 0; // not done end; ``` 导出效果如下: ###### GetHttpResponseHeader 用途:网络访问以及相关函数相关函数。 参数:无。 返回:处理后的结果值。 范例 获取指定网页的头部信息 ```tsl sid := createhttpsession(); url := "http://www.baidu.com"; r := GetHttp(url, 60000, v, code); hd := GetHttpResponseHeader(); return hd; ``` 返回如下: ###### SysSendMail 用途:通过 SMTP 服务器发送邮件。 参数:见下方定义与参数说明。 返回:发送成功返回 true,失败返回 false;可通过 Msg 获取错误信息。 说明:利用SMTP服务器发送邮件,成功返回真,否则返回假。如果有MSG这个参数,则当失败的时候返回失败的具体信息到MSG参数。 定义一:SysSendMail(AHost,ASubject,ATo,AFrom,AText:String;[Var Msg:String]):Boolean; 参数: 定义二:SysSendMail(AHost,ASubject,ATo,AFrom,AText,ACharSet,ABccList,ACCList:String; APriority:Integer;[[…]][Var Msg:String]):Boolean; 参数: 附件可选参数,AttachmentName和AttachmentContent任意对参数组合。 AttachmentName..:添加的附件在邮件里的文件名称。 AttachmentContent..:添加的附件的内容,如果该内容为字符串类型且存在该文件,则将文件内容作为附件内容。 MSG:用于接收错误信息的参数,可省略。 返回:如果发送成功,则返回1,否则返回0; 范例: ```tsl // 范例一: ret := rdo2 SysSendMail("www.tinysoft.com.cn", '客户端发邮件测试', 'xulihua@tinysoft.com.cn', 'support@tinysoft.com.cn', 'Tinysoft hello', msg); return ret; // 结果:1 // 范例二: ret := rdo2 SysSendMail("www.tinysoft.com.cn", '客户端发邮件测试', 'xulihua@tinysoft.com.cn', 'support@tinysoft.com.cn', '邮件测试:Tinysoft', 'gb2312', 'wuxinxing@tinysoft.com.cn', 'chenjuan@tinysoft.com.cn', 1, '附件测试', 'D:\\test1\\test.tsl', msg); return ret; // 返回:1,发送的附件为 "附件测试.dat" ``` 范例三:通过QQ邮箱发送邮件。注意,通过QQ邮箱发送邮件,需要使用QQ账户和账户授权码。授权码的获取参照步骤说明进行配置并获取: http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256 ```tsl // 通过调用类smtp设置配置信息及发送邮件 function SendEmailTest_QQ(); begin return rdo2 SendEamailTest(); end; function SendEamailTest(); begin obj := CreateObject("smtp"); obj.UserName := '510543292'; // 邮箱账号(用户QQ账号) obj.Password := 'abcdefg'; // 安全验证码(用户QQ的授权码) obj.UseTLS := 1; // 安全传输协议 obj.Host := 'smtp.qq.com'; // smtp服务器 // obj.AuthType := 1; obj.port := 465; // smtp服务器端口 465或587 try Ret := obj.Connect(); echo ret; except return echo "\r\nconnect fail\r\n"; end; msg := CreateObject("MailMsg"); msg.subject := "邮件发送测试"; // 文件标题 msg.from := "510543292@qq.com"; msg.ContentType := 'text/html; charset="gb2312"'; msg.body := "定时任务调度"; // 文件内容 msg.Sender := "510543292@qq.com"; // 邮件发送人 msg.Recipients := "510543292@qq.com"; // 邮件接收人 try echo obj.send(msg); echo msg; except echo '\r\n邮件错误信息', obj.LastCmdResult(); return echo '\r\n邮件发送失败:', ExceptObject.errinfo; end; return echo 'over'; end; ``` 范例四:通过QQ邮箱发送邮件。注意,通过QQ邮箱发送邮件,需要使用QQ账户和账户授权码。授权码的获取参照步骤说明进行配置并获取: http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256 ```tsl //发送邮件的用户名及授权码的配置写在\tinysoft\analyse.net\plugin\fileMgr.ini 文件里 { fileMgr.ini 文件中配置语句如(端口465或587): [Smtp Settings] smtp.QQ.COM:UseTLS=1 smtp.QQ.COM:Port=465 smtp.QQ.COM:UserName=510543292 smtp.QQ.COM:Password=abc smtp.QQ.COM := smtp.QQ.COM } ret := SysSendMail("smtp.qq.com", '客户端发邮件测试', '510543292@qq.com', '510543292@qq.com', 'Tinysoft hello', msg); return msg; ``` ####### 内容 - SMTP登录以及配置文件 ####### SMTP登录以及配置文件 一旦SMTP服务器需要登录,我们必须先在配置文件中设置好,才可以使用SYSSENDMAIL指定的HOST。 配置文件为PLUGIN\FileMgr.INI,在其中加入如下配置: [Smtp Settings] MOFT.COM:Port=25 MOFT.COM:UserName=Bill MOFT.COM:Password=Gates MOFT.COM=Mail.MOFT.COM 端口默认为25,地址默认为HOST别名相同,密码允许采用加密存贮,如需要加密请使用CONNECTMAN工具进行加密。 ##### INI文件处理函数 INI文件处理函数主要读取INI文件的结名称、键名称、键值。用中括号[]括起来即结名称,每个节名称下面的是相关的键名键值等。 ###### 内容 - IniReadBool - IniReadDate - IniReadDateTime - IniReadFloat - IniReadInteger - IniReadTime - IniReadString - IniReadBinaryStream - IniReadSection - IniReadSections - IniReadSectionValues - IniSectionExists - IniValueExists - IniWriteBool - IniWriteDate - IniWriteDateTime - IniWriteFloat - IniWriteInteger - IniWriteTime - IniWriteString - IniWriteBinaryStream - IniDeleteKey - IniEraseSection - 宽字节处理函数 ###### IniReadBool 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata1的键名称为bool的键值,返回布尔值。 节内容为: [IniData1] bool := 1 } ret := rdo2 IniReadBool("", "C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini","Inidata1","bool",0); return ret; //结果:1 ``` ###### IniReadDate 用途:日期时间处理函数。 参数:无。 返回:日期或时间值。 范例 ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata2,键名称为date的日期值,如果该值不是标准的日期格式‘年-月-日’,则返回默认的日期defualt 节内容为: [IniData2] date := 2014-1-1 } day := today(); ret := rdo2 IniReadDate("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata2","date",day); return ret; //结果:41640 ,即日期 2014-01-01 ``` 老版本使用范例: ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata2,键名称为date的日期值,如果该值不是标准的日期格式‘年/月/日’,则返回默认的日期defualt 节内容为: [IniData2] date := 2014/1/1 } day := today(); ret := rdo2 IniReadDate("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata2","date",day); return ret; //结果:41640 ,即日期 2014-01-01 ``` 新旧版本的过渡,在新版本中可以通过setformatlocalcode(936)来设定当前的转换规则,达到老版本的效果,比如配置文件内容为: {[IniData2] date=2014/1/1 } 在新版客户端中执行代码: ```tsl day := today(); rdo2 setformatlocalcode(936); ret := rdo2 IniReadDate("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini", "Inidata2", "date", day); return ret; ``` 返回: 41640 ,即日期 2014-01-01 ###### IniReadDateTime 用途:日期时间处理函数。 参数:无。 返回:日期或时间值。 范例 ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata3,键名称为datetime的日期值,如果该值不是标准的日期格式‘年-月-日 时:分:秒’,则返回默认的日期时间defualt 节内容为: [IniData3] datetime := 2014-1-1 14:00:00 } day := today(); ret := rdo2 IniReadDateTime("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata3","datetime",day); return ret; //结果:41640.58333333 ,即日期时间 2014-01-01 14:00:00 ``` 老版本使用范例: ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata3,键名称为datetime的日期值,如果该值不是标准的日期格式‘年/月/日时:分:秒’,则返回默认的日期时间defualt 节内容为: [IniData3] datetime := 2014/1/1 14:00:00 } day := today(); ret := rdo2 IniReadDateTime("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata3","datetime",day); return ret; //结果:41640.58333333 ,即日期时间 2014-01-01 14:00:00 ``` 新旧版本的过渡,可参考:IniReadDate ###### IniReadFloat 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata4,键名称为Float的实数值,如果该值不是实数,则返回默认值defualt 节内容为: [IniData4] float := 3.14 } ret := rdo2 IniReadFloat("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata4","float",2.5); return ret; //结果:3.14 ``` ###### IniReadInteger 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata5,键名称为INT的整数值,如果该值不是整数,则返回默认值defualt 节内容为: [IniData5] INT := 3 } ret := rdo2 IniReadInteger("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata5","INT",5); return ret; //结果:3 ``` ###### IniReadTime 用途:日期时间处理函数。 参数:无。 返回:日期或时间值。 范例 ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata6,键名称为time的时间值,如果该值不是时间型‘hh:mm:ss’,则返回默认值defualt 节内容为: [IniData6] time := 14:00:00 } ret := rdo2 IniReadTime("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata6","time",0.5); return ret; //结果:0.58333333 ,即时间 14:00:00 {注意,返回的值跟小数的设置有关,小数点越大,数据越精确,后面获得的时间类型也越准确} ``` ###### IniReadString 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata7,键名称为String的字符串 节内容为: [IniData7] String := Tinysoft } ret := rdo2 IniReadString("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata7","String",'error'); return ret; //结果:Tinysoft ``` ###### IniReadBinaryStream 用途:INI文件处理函数相关函数。 参数: 返回:处理后的结果值。 范例 以下范例中,都是对下面的bs.ini文件进行的操作,bs.ini文件内容如下: 范例01:不传入第五个参数,读取ini文件中Test节点中的Bs01键对应的内容 ```tsl // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 读取data rt := IniReadBinaryStream("", iniFilePath, "Test", "Bs01"); return rt; ``` 范例02:第五个参数值为0,读取ini文件中Test节点中的Bs02键对应的内容 ```tsl // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 读取data rt := IniReadBinaryStream("", iniFilePath, "Test", "Bs02", 0); return rt; ``` 范例03:第五个参数值为1,读取ini文件中Test节点中的Bs03键对应的内容 ```tsl // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 读取data rt := IniReadBinaryStream("", iniFilePath, "Test", "Bs03", 1); return rt; // 返回值:"Be7iArVxfj8q" ``` 范例04:第五个参数值为2,读取ini文件中Test节点中的Bs04键对应的内容 ```tsl // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 读取data rt := IniReadBinaryStream("", iniFilePath, "Test", "Bs04", 2); return String(rt); // 返回值:"Be7iArVxfj8q" ``` 范例05:第五个参数类型为TStream类型,读取ini文件中Test节点中的Bs05键对应的内容 ```tsl // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 创建TStream对象,用于读取 rs := new TMemoryStream(); rt := IniReadBinaryStream("", iniFilePath, "Test", "Bs05", rs); { // 由于读到的stream类型的内容是存放在rs变量中,由于steam类型的数据流不可读, // 本案例中将其数据值导出到本地的stm文件中,然后再导入该数据进行结果的展示 // 操作如下: } // 将rs导出为STM文件 rs.SaveToFile("", "D:\\test\\rsData.STM"); // 读取STM文件 if not importFile(ftStream(), "", "D:\\test\\rsData.STM", re)then return "获取导入数据失败"; return array(rt, re); // rt为rs内容的字节长度,re为转为STM格式后的数值 ``` ###### IniReadSection 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl { 读取本地文件:C:\program Files\Tinysoft\Analyse.NET\Plugin\filemgr.ini中节名称为test的所有键名。 节内容为: [test] Dir := d:\test1permitRead=tsmodel permitWrite := tsmodel UserPrivate := 0 } ret := rdo2 IniReadSection("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\filemgr.ini","test"); return ret; ``` ###### IniReadSections 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl { // 读取本地文件:C:\program Files\Tinysoft\Analyse.NET\Plugin\test.ini中的所有节名称 } ret := rdo2 IniReadSections("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini"); return ret; ``` ###### IniReadSectionValues 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\filemgr.ini中节名称为test的所有键名及键名内容 节内容为: [test] Dir := d:\test1permitRead=tsmodel permitWrite := tsmodel UserPrivate := 0 } ret := rdo2 IniReadSectionValues("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\filemgr.ini","test"); return ret; ``` ###### IniSectionExists 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {读取本地文件:C:\program Files\Tinysoft\Analyse.NET\Plugin\test.ini, // 判断是否存在节名称为Inidata8的数据配置 } ret := rdo2 IniSectionExists("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini", "Inidata8"); return ret; // 结果:1 ``` ###### IniValueExists 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {读取本地文件:C:\program Files\Tinysoft\Analyse.NET\Plugin\test.ini, // 判断是否存在节名称为Inidata8,且键名为byte的数据配置 } ret := rdo2 IniValueExists("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini", "Inidata8", "byte"); return ret; // 结果:1 ``` ###### IniWriteBool 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {写本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini, 设置节内容为: [IniData9] bool := 1 } ret := rdo2 IniWriteBool("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata9","bool",1); return ret; //结果:0,写入成功 ``` 文件写入: ###### IniWriteDate 用途:日期时间处理函数。 参数:无。 返回:日期或时间值。 范例 ```tsl {写本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini, 设置节内容为: [IniData2] date := 2014/1/12 } ret := rdo2 IniWriteDate("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata2","date",41651); return ret; //结果:0 ,设置成功 ``` 文件修改: ###### IniWriteDateTime 用途:日期时间处理函数。 参数:无。 返回:日期或时间值。 范例 ```tsl {写本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini, 设置节内容为: [IniData3] datetime := 2014/1/12 14:00:00 } ret := rdo2 IniWriteDateTime("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata3","datetime",41651.5833334); return ret; //结果:0,修改成功 ``` 文件修改: ###### IniWriteFloat 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {写本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini, 设置节内容为: [IniData4] float := 9.9 } ret := rdo2 IniWriteFloat("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata4","float",9.9); return ret; //结果:0,修改成功 ``` 文件修改: ###### IniWriteInteger 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {写本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini, 设置节内容为: [IniData5] INT := 100 } ret := rdo2 IniWriteInteger("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata5","INT",100); return ret; //结果:0,修改成功 ``` 文件修改: ###### IniWriteTime 用途:日期时间处理函数。 参数:无。 返回:日期或时间值。 范例 ```tsl {写本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini, 设置节内容为: [IniData6] time := 12:00:00 } ret := rdo2 IniWriteTime("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","Inidata6","time",0.5); return ret; //结果:0,修改成功 ``` 文件修改: ###### IniWriteString 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {写本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini, 设置节内容为: [IniData7] String := Hello Tinysoft } ret := rdo2 IniWriteString("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini","IniData7","String",'Hello Tinysoft'); return ret; //结果:0,修改成功 ``` 文件修改: ###### IniWriteBinaryStream 用途:INI文件处理函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:写入数据类型为数组,数据写入至ini文件中Write节点的Bs01键中 ```tsl data := array(1, 2, 3, 4); // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 写入data ret := IniWriteBinaryStream("", iniFilePath, "Write", "Bs01", data); return ret; // 返回值:0 ``` ini文件内容: 范例02:写入数据类型为字符串,数据写入至ini文件中Write节点的Bs02键中 ```tsl data := "Be7iArVxfj8q"; // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 写入data ret := IniWriteBinaryStream("", iniFilePath, "Write", "Bs02", data); return ret; // 返回值:0 ``` ini文件内容: 范例03:写入数据类型为Binary,数据写入至ini文件中Write节点的Bs03键中 ```tsl data := binary("Be7iArVxfj8q"); // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 写入data ret := IniWriteBinaryStream("", iniFilePath, "Write", "Bs03", data); return ret; // 返回值:0 ``` ini文件内容: 范例04:写入TStream类型的数据,数据写入至ini文件中Write节点的Bs04键中 Data.STM中内容为"Be7iArVxfj8q" ```tsl // 创建TStream对象,用于写入 ws := new TMemoryStream(); // 从Data.STM文件中加载数据 ws.LoadFromFile("", "D:\\test\\Data.STM"); // INI文件地址 iniFilePath := "D:\\test\\bs.ini"; // 写入data ret := IniWriteBinaryStream("", iniFilePath, "Write", "Bs04", ws); return ret; // 返回值:0 ``` ini文件内容: ###### IniDeleteKey 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {删除本地文件:C:\program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节Inidata9的键名为bool的内容} ret := rdo2 IniDeleteKey("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini", "Inidata9", "bool"); return ret; // 结果:0,删除成功 ``` ###### IniEraseSection 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl {删除本地文件:C:\program Files\Tinysoft\Analyse.NET\Plugin\test.ini中节名称为Inidata8的内容,包括节名称、键名、键值 } ret := rdo2 IniEraseSection("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini", "Inidata8"); return ret; // 结果:0,删除成功 ``` ###### 宽字节处理函数 ####### 内容 - IniReadSectionsw ####### IniReadSectionsw 用途:INI文件处理函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl // 读取本地文件:C:\Program Files\Tinysoft\Analyse.NET\Plugin\test.ini中的所有节名称 ret := rdo2 IniReadSectionsw("", "C:\\Program Files\\Tinysoft\\Analyse.NET\\plugin\\test.ini"); return ret; // 返回 ``` ##### 进程相关函数 ###### 内容 - SysPutenv - 子进程相关函数 - SysGetLastError - SysExec - SysParamStr - SysErrorMessage - Sysgetenv - SysWaitForMultipleObjects - SysTerminate - SysCreateMutex - SysCloseHandle - SysCmdLine - SysReleaseMutex - 运行进程的环境变量 - SysProcessID - SysParamcount - SysThreadID - Sleep - SysWaitForSingleObject - SysGetenvs - SysexecReadpipe - SysexecGetenvs - SysexecDeletepipe - SysexecSetenvs - SysexecNewpipe - SysExecWritepipe - 获取COM进程 - TSL解释器对网格计算的支持 - SysExec定义二 - dbglocalrunning - dbglocalcancel - SysThreadSelf - syslinuxkrnlclosemutex - SysSetThreadPriority - SysGetThreadPriority - SysSetProcessPriority - SysGetProcessPriority - SysGetProcessList - SysGetProcessListw - SysGetProcessNamePath - SysGetProcessNamePathw - SysGetProcessCmdLine - SysGetProcessCmdLinew - SysSetThreadName - SysGetThreadName - SysGetThreads - SysPPid - SysGetSubProcesses - SysKill - SysPidOfTid - SysPidOfHandle - SysHandleOfPid ###### SysPutenv 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 以笔者的电脑环境为例,来展示该函数的功能: 如图所示,本地现有名为OS的环境变量: 并且在powerShell等控制台中可以获取到: 在TSL执行环境中,我们可以使用SysGetenv函数获取指定环境变量,如下: 范例01:将原环境变量值替换为设置值。 从下面的截图中,可以看出,SysPutenv只能设置当前TSL运行环境的环境变量。 在客户端中用代码实现如下: ```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" ``` 参考Sysgetenv 、 Sysgetenvs ###### 子进程相关函数 运行控制台进程设置输入输出的管道 默认情况下,控制台进程的输入是键盘,控制台进程的输出是控制台的屏幕。如果我们需要实现一些特殊的操作,例如给控制台程序发送命令,或者得到控制台程序的输出内容,这样我们就需要用到管道来实现这个功能。 ###### SysGetLastError ###### SysExec 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:播放视频 ```tsl // 调用windows media player的进程,播放文件D :\\test1\\when_ever.flv toolPath := "C:\\Program Files\\Windows Media Player"; ret := rdo2 SysExec(toolPath + "\\wmplayer.exe", "D:\\test1\\when_ever.flv", toolPath, 1, return code); return ret; ``` 参考SysCloseHandle SysTerminate、 SysexecNewpipe ###### SysParamStr 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 本地test.tsl文件中代码如下: ```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 ###### SysErrorMessage 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl return rdo2 SysErrorMessage(200); // 结果:代码段不可大于或等于 64K。 ``` ###### Sysgetenv 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 读取本地已有系统环境变量OS的值 return Sysgetenv("OS"); // 返回字符串“Windows_NT” ``` 注:更具体的应用可参考Sysputenv中的范例。参考Sysputenv 、 Sysgetenvs ###### SysWaitForMultipleObjects 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl SysexecNewpipe(); // 创建管道 path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; doS1 := array('C:\\TinySoftNG\\AnalyseNG.NET\\tsl.exe', 'C:\\DoTSL\\otherTest\\TestEnv.tsl'); doS2 := 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, doS1, nil, false, code); hand3 := SysExec(path, doS2, 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: ```tsl sleep(500);t := Sysgetenvs();echo "sys: ", tostn(t), '\r\n';return 1; ``` TestEcho.tsf: ```tsl sleep(2 * 1000); // 停2秒echo 'TestEchoIN\r\n';return 1; ``` 参考SysExec、 SysWaitForSingleObject ###### SysTerminate 参考SysCloseHandle SysExec ###### SysCreateMutex 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 创建一个名称为tinysoft的互斥锁 ret := rdo2 SysCreateMutex("tinysoft"); return ret; // 结果:2632 ``` ###### SysCloseHandle 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 启动windows平台下的windows命令处理程序,然后关闭启动该程序时返回的句柄 toolPath := "C:\\Program Files\\Windows Media Player"; ret := rdo2 sysExec(toolPath + "\\wmplayer.exe", "D:\\test1\\when_ever.mp3", toolPath, 1, return code); ret1 := rdo2 SysCloseHandle(ret); return ret1; // 结果:1 ``` 参考SysExec SysTerminate ###### SysCmdLine ###### SysReleaseMutex 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 释放互斥锁,参数为创建互斥锁时返回的互斥锁编号 ret := rdo2 SysCreateMutex("tinysoft"); ret1 := rdo2 SysReleaseMutex(ret); return ret1; // 结果:1 ``` ###### 运行进程的环境变量 一个进程的环境块会影响一个进程的行为,一些是通用的系统环境块,例如windows里的path和linux里的PATH以及LD_LIBRARY_PATH,另外一些是进程所依赖的特殊的环境,例如java有java运行的特殊环境变量 注意:在windows里常用的环境变量为path,是运行和加载DLL的查找路径 在linux里PATH表明执行的路径,LD_LIBRARY_PATH用来标识加载DLL的查找路径 在多路径的分隔符,windows里采用“;”进行分割,而linux采用“:”进行分割 Linux里的环境变量等名称大小写相关,而windows环境变量大小写不相关 例如在windows里sysgetenv("path")和sysgetenv("PATH")的结果是一样的 而在linux里必需使用sysgetenv("PATH") ###### SysProcessID 用途:获取当前进程 ID(PID)。 参数:无。 返回:进程 ID(整数)。 范例 ```tsl {获得天软客户端程序当前的进程ID,即在任务管理器中查看到的进程对应的PID。每个电脑的进程不一样} return rdo2 SysProcessID(); ``` ###### SysParamcount 用途:获取命令行传入参数的个数。 参数:无。 返回:整数。 范例 本地test.tsl文件中代码如下: ```tsl test(); function test(); begin // 获取命令行传入参数个数 echo SysParamcount(); end; ``` 在cmd中打开文件所在文件夹,输入命令:tsl test.tsl 1 2 3 ###### SysThreadID 用途:获取当前线程 ID。 参数:无。 返回:线程 ID(整数)。 范例 ```tsl // 获得天软客户端程序当前的进程运行的线程ID return rdo2 SysThreadID(); ``` ###### Sleep 用途:让当前线程休眠指定毫秒数。 参数: 返回:无。 范例 ```tsl // 以下代码先打印123,接着回暂停2S,然后接着打印456 echo 123; Sleep(2000); echo 456; ``` ###### SysWaitForSingleObject 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl SysexecNewpipe(); // 创建管道 path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; doS := array('C:\\TinySoftNG\\AnalyseNG.NET\\tsl.exe', 'C:\\DoTSL\\otherTest\\TestEnv.tsl'); hand1 := SysExec(path, doS, nil, array('wait':false, 'in':'d := "123"\r\n'), code); r := SysWaitForSingleObject(hand1, 10 * 1000); // 等待线程的状态 t := SysexecReadpipe(); // 读取管道内容 return array(r, t); ``` 返回:其中,TestEnv.tsl文件的实现如下: ```tsl // 当前sys的环境变量t:=Sysgetenvs();echo "sys: ",tostn(t),'\r\n';s:=Readln(); // 读取echo 'IN:',s,'\r\n';return 1; ``` 参考SysExec、 SysWaitForMultipleObjects ###### SysGetenvs 用途:进程相关函数相关函数。 参数:无。 返回:处理后的结果值。 范例读取当前运行环境的所有环境变量 ```tsl return SysGetenvs(); ``` 部分结果截图: 参考Sysputenv 、 Sysputenv ###### SysexecReadpipe 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例非阻塞模式下输出内容的读取 ```tsl pyPath := "D:\\Program Files\\Python\\Python38\\python.exe"; pyCmd := "py -u D:\\project\\python\\test.py"; // 创建读写管道 ret := SysexecNewpipe(0); if ret then handle := SysExec(pyPath, pyCmd, nil, false, code); // 获取SysExec进程所在管道的输出内容 Res := ""; while res = ""do begin res := SysexecReadpipe(handle); sleep(100); // 100毫秒读取一次 end; SysTerminate(code, handle); // 终止进程 return res; ``` 注:其中test.py的内容如下: 参考SysExec、 SysexecNewpipe 、 Sysexecdeletepipe 、 Sysexecdeletepipe 、 SysExecWritePipe ###### SysexecGetenvs 用途:进程相关函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl Sysexecsetenvs(array("test=test", "test1=test1"), 2); return SysexecGetenvs(); ``` 注:更多应用可参考Sysexecsetenvs参考SysExec、 Sysexecsetenvs ###### SysexecDeletepipe 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```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; deRet := SysexecDeletepipe(hand); // 删除成功,尝试向指定进程所在管道写入内容 if deRet then begin try SysexecWritepipe(hand, " datetostr(20221130T)\r\n"); return false; except // 写入失败,管道删除成功 return true; end; end; SysTerminate(code, hand); // 终止进程 return false; ``` 参考SysExec、 SysexecNewpipe 、 Sysexecdeletepipe 、 Sysexecreadpipe 、 SysExecWritePipe ###### SysexecSetenvs 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:仅设置的环境变量有效,不使用本地系统环境变量 ```tsl // 设置环境变量,不使用系统环境变量 SysexecSetenvs(array("test=test", "test1=test1"), 0); return SysexecGetenvs(); ``` 范例02:设置环境变量,添加到系统环境变量之后 ```tsl SysexecSetenvs(array("test=test", "test1=test1"), 1); return SysexecGetenvs(); ``` 部分结果截图: 范例03:设置子进程中的环境变量 ```tsl // 创建读写管道 SysexecNewpipe(); path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; doS := array('C:\\TinySoftNG\\AnalyseNG.NET\\tsl.exe', 'C:\\DoTSL\\otherTest\\TestEnv.tsl'); SysexecSetenvs(array('Test=D:\\Test', 'Test1=D:\\Test1'), 0); b1 := SysexecGetenvs(); // 第一个子进程:非阻塞执行,返回进程句柄 hand := SysExec(path, doS, nil, 0, code); // 获取SysExec进程所在管道的输出内容 t1 := ''; while t1 = ''do begin t1 := SysexecReadpipe(hand); // 循环读取进程的输出内容 sleep(100); // 100毫秒读取一次 end; return t1; ``` 返回:子进程环境变量设置成功 其中,TestEnv.tsl脚本的内容如下: ```tsl t := Sysgetenvs(); echo "sys: ", tostn(t), '\r\n'; t := Sysexecgetenvs(); echo "sysExec: ", tostn(t), '\r\n'; ``` 范例04:设置多个子进程中的环境变量 ```tsl // 创建读写管道 SysexecNewpipe(); path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; SysexecSetenvs(array('Test=D:\\Test', 'Test1=D:\\Test1'), 0); b1 := SysexecGetenvs(); // 第一个子进程:非阻塞执行,返回进程句柄 hand := SysExec(path, 'tsl', nil, array('wait':false, 'in':'a := "第一个进程"\r\n'), code); // 通过管道获取子进程中的当前环境变量 SysexecWritepipe(hand, "sys1 := Sysgetenvs()\r\n"); sleep(500); // 等待命令执行 // 获取SysExec进程所在管道的输出内容 t1 := ''; while t1 = ''do begin t1 := SysexecReadpipe(hand); // 循环读取第一个进程的内容 sleep(100); // 100毫秒读取一次 end; SysexecNewpipe(); // 再次创建管道 // 重设子进程的环境变量组 SysexecSetenvs(array('Test=D:\\AAATest', 'BBB=D:\\Test1'), 0); b2 := SysexecGetenvs(); // 第二个子进程: hand2 := SysExec(path, 'tsl', nil, array('wait':false, 'in':'b := "第二个进程"\r\n'), code); // 通过管道获取子进程中的当前环境变量 SysexecWritepipe(hand2, "sys2 := Sysgetenvs()\r\n"); sleep(500); // 等待命令执行 // 获取SysExec进程所在管道的输出内容 t2 := ''; while t2 = ''do begin t2 := SysexecReadpipe(hand2); // 循环读取第二个进程的内容 sleep(100); // 100毫秒读取一次 end; SysTerminate(code, hand); // 终止进程 SysTerminate(code, hand2); // 终止进程 return t1 + t2; ``` 返回:对Sysexec进程设置的环境变量有生效 参考SysExec、 Sysexecgetenvs ###### SysexecNewpipe 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```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); ``` 返回结果如下图: 参考SysExec、 Sysexecdeletepipe 、 Sysexecdeletepipe 、 Sysexecreadpipe 、 SysExecWritePipe ###### SysExecWritepipe 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl // 创建读写管道 SysexecNewpipe(0); path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; // 非阻塞执行,返回进程句柄 hand := SysExec(path, "tsl", nil, false, code, 5000); // 向SysExec进程所在管道写入内容 SysExecWritepipe(hand, "datetostr(20221130T)\r\n"); // 获取SysExec进程所在管道的输出内容 t1 := ""; while t1 = ""do begin t1 := SysexecReadpipe(hand); sleep(100); // 100毫秒读取一次 end; SysTerminate(code, hand); // 终止进程 return t1; ``` 参考SysExec、 SysexecNewpipe 、 Sysexecdeletepipe 、 Sysexecdeletepipe 、 Sysexecreadpipe ###### 获取COM进程 在一些应用开发过程中,比如office文档的调用实现中,由于office程序的不稳定现象,当我们在程序中调用了office的com进程时,office发生了错误,则会引发许多异常问题,如一直等待、或程序无法退出,或进程被挂起等等异常,此时,我们就非常希望能过将该异常的进程进行强制退出。那么,在多个进程的环境下,如何才能准确找到我需要终止的进程呢? 为此,天软提供了SyxGetPidOfCom等函数,可以通过指定Com对象,得到该Com服务的进程ID,从而实现精准强制终止的操作。 ####### 内容 - 进程ID与获取方式 - SysGetPidOfCom - SysGetWndOfCaption - SysGetPidtidOfWnd - 实例展示 ####### 进程ID与获取方式 进程ID(PID)是大多数操作系统的内核用于唯一标识进程的一个数值。这一数值可以作为许多函数调用的参数,从而可以实现调整进程优先级、资源分配、关闭进程等的进程控制。 由于com结构中,进程ID只做了16位二进制的记录,导致其获取到的进程大小存在限制,即当进程ID<65535才有效,一旦返回值为65535则表示进程ID超过65535,就获取不到真实的进程ID,此时,我们可以通过获取窗口的进程ID来解决这个问题。 窗口句柄,每个窗口在被创建出来之后就会被赋予一个句柄,该句柄(句柄实则上是一个指针)指向一个数据结构体,结构体里明确表示着该窗口的各种信息,窗口大小,窗口名等,当我们得到这个句柄时就可以请求操作系统对它做一系列操作,例如:移动窗口,关闭窗口,最小化最大化等。 所以,获得进程ID和窗口句柄就可以灵活实现各种功能。 因此,天软提供两种获取Com服务进程ID的方式,如下: ####### SysGetPidOfCom 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取TSL创建的word.application对象的进程ID。 ```tsl getoleobject("Word.application", 0, v); // 获取ComObj对象 PID := SysGetPidOfCom(v); // 通过COM对象获取进程ID Echo PID; ``` ####### SysGetWndOfCaption 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 获取标题是”test.docx”的窗口句柄。 ```tsl V := SysGetWndOfCaption("test.docx"); Echo V; ``` ####### SysGetPidtidOfWnd 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 获取标题是”test.docx”的窗口的word的进程ID。 ```tsl // 获取标题是”test.docx”的窗口句柄 Wnd := SysGetWndOfCaption("test.docx"); // 通过窗口句柄获得进程ID V := SysGetPidtidOfWnd(wnd[0]); Echo v; ``` ####### 实例展示 ######## 内容 - 通过窗口句柄实现对窗口最大化、最小化 - 通过进程id实现对进程关闭 ######## 通过窗口句柄实现对窗口最大化、最小化 通过TSL获取窗口句柄后,可以使用一些windows自带的API接口对其进行操作。 以下就是通过Windows用户界面相关应用程序接口user32.dll中的ShowWindow,对一个test.docx窗口进行最大化,最小化(默认已经打开了此窗口)的样例代码。 ```tsl // 获取窗口句柄 wnd := SysGetWndOfCaption("test.docx"); // 是否获取成功,不成功就退出。 if not ifarray(wnd) then return 1; // 最小化 ShowWindow(wnd[0], 2); sleep(2000); // 最大化 ShowWindow(wnd[0], 3); sleep(2000); // 最小化 ShowWindow(wnd[0], 2); sleep(2000); // 最大化 ShowWindow(wnd[0], 3); sleep(2000); return 1; // TSL调用user32.dll中的ShowWindow函数。 function ShowWindow(hwnd:integer;nCmdShow:integer):boolean;external"user32.dll"name"ShowWindow"; ``` ######## 通过进程id实现对进程关闭 通过进程id对进程的关闭,比如,office中因为某些原因导致崩溃或者挂起时,就可以通过获取程ID将其关闭。 以下就是通过进程ID关闭整个winword进程。 ```tsl // 通过"test.docx"获得窗口句柄("test.docx"已打开) wnd := SysGetWndOfCaption("test.docx"); if not ifarray(wnd) then return 1; // 通过窗口句柄获得winword进程的pid pid := SysGetPidtidOfWnd(wnd[0]); if pid <= 0 then return 1; // 通过taskkill系统命令关闭winword进程 execHandle := sysExec('C:\\Windows\\System32\\taskkill.exe', ' /pid '$inttostr(pid)$' /f', 0, 0, return code); return 1; ``` ###### TSL解释器对网格计算的支持 天软本地脚本执行支持多线程,多线程执行采取的是线程池模式。语法与客户端使用的一样简单。只需要在一个函数或者语句前面加一个#就是把它抛给了某个线程去执行了。所以代码由普通模式改成网格模式不需要原代码作很大修改。 网格使用格式:R[i]:=#函数名(参数…) with array(”PN1”:p1,”PN2”:p2,…) 其中,with后面可以带入其它参数,如需要带入主程中的相关环境等系统参数时可用,在被调子程序中可通过getsysparam(“pName”)或getsysparams()等方式获取。 本地解释器默认是启动了网格的状态,且默认为128个最大线程。 若用户需要另外修改该配置,可以通过添加TSL.ININ文件的方式进行配置相关参数。 ####### 内容 - TSL.INI配置说明 - 使用范例 ####### TSL.INI配置说明 第一步:在天软安装目录下,添加TSL.INI文件(存放目录与TSL.exe解释器文件保存一致)。 第二步:配置TSL.INI文件内容与参数 [multitask] #######本地网格计算启动的最大线程数---用户可修改其值 maxthread=128 #######最大计算任务的等待队列---用户可修改其值 maxpending=16777216 #######未完成的任务等待判断间隔毫秒数---用户可修改其值 busyinterval=3000 #######最大等待的次数---用户可修改其值 busyretry=100000格式如下: 其中,maxthread即是设置最大网格线程数,当设置为maxthread=10时,则网格线程数不能超过10个。 第三步:保存后,重启客户端或重启解释器,就能生效。 例如:dosumN函数需要占用约1秒钟的时间,并发执行10次dosumN函数,大约2秒左右可以完成 ```tsl mtic; r := array(); for i := 0 to 9 do r[i] := # dosumN(i); b := array(); for j := 0 to length(r) - 1 do b[j] := dupvalue(r[j]); // 对并发结果进行访问,即对各网格进行等待获取结果 echo 'time-', mtoc, '\r\n'; echo tostn(b); return 1; function dosumN(n); begin sleep(1 * 1000); // 暂停1秒 return sum(0 - > n); end; ``` 运行表现如下: ####### 使用范例 在设置为5个最大线程数的情况下,运行10个线程,每个线程暂停5秒并返回id编号和线程号。 最后,打印所有的线程id编号和线程号,和程序运行时间,运行时间10秒多一点说明,最大线程数设置成功。 代码如下: ```tsl mtic; a := array(); for i := 0 to 9 do begin a[i] := #multirun(i); // 语句前增加标识#即可执行多线程。 end; echo tostn(a); echo "总花费秒数为:", mtoc; return 1; function multirun(id); begin sleep(5000); return array(id, systhreadid()); end; ``` ###### SysExec定义二 范例: 范例01:阻塞方式调用子进程执行命令 ```tsl path := "D:\\Program Files\\Python\\Python38\\python.exe"; // 创建管道 ret := Sysexecnewpipe(); // 创建成功,执行命令:获取python的版本号 if ret then handle := SysExec(path, "py -V", nil, true, code, 5000); else return false; return code; ``` 范例02:调用子进程执行TSL语言脚本 主程序代码: ```tsl path := "D:\\Program Files\\AnalyseNG.NET\\TSL.exe"; filepath := "D:\\test\\csv\\test.tsl"; // 创建管道 ret := Sysexecnewpipe(); // 创建成功,执行TSL语言脚本 if ret then handle := SysExec(path, "tsl "$filepath, nil, true, code, 5000); else return false; return code; ``` test.tsl代码: ```tsl data := array((1, 2, 3), (4, 5, 6), (7, 8, 9)); ret := ExportFile(ftxls(), "", "D:\\test\\csv\\test.xlsx", data); // 导出成功,返回码为1 if ret = 1 then begin echo "ExportFile Success"; systerminate(1); end else begin echo "ExportFile Fail:"$ret; // 导出成功,返回码为0 systerminate(0); end; return; ``` 导出文件内容: 范例03:非阻塞方式下执行命令并获取输出内容 ```tsl path := "D:\\Program Files\\Python\\Python38\\python.exe"; // 创建管道 ret := Sysexecnewpipe(); // 创建成功,执行命令:获取python的版本号 if ret then handle := SysExec(path, "py -V", nil, false, code); else return false; // 循环获取执行后的输出内容 t1 := ""; while t1 = ""do begin t1 := SysexecReadpipe(handle); sleep(100); // 等待100毫秒 end; SysTerminate(code, handle); // 终止进程 return t1; ``` 范例04:非阻塞模式下通过”in”与管道输入串 ```tsl // 创建读写管道 SysexecNewpipe(0); path := "D:\\TinySoftNG\\AnalyseNG.NET\\TSL.exe"; // 非阻塞执行,返回进程句柄,并输入命令a:="abc",'\r\n'表示回车功能 hand := SysExec(path, "tsl", nil, array('wait':0, 'in':'a := "abc"\r\n'), code); // 向SysExec进程所在管道写入内容 SysexecWritepipe(hand, "datetostr(20221130T)\r\n"); sleep(500); // 等待'in'传入的命令执行完成 // 向管道写入获取变量a的值 SysexecWritepipe(hand, "a\r\n"); // 获取SysExec进程所在管道的输出内容 t1 := ""; while t1 = ""do begin t1 := SysexecReadpipe(hand); sleep(100); // 100毫秒读取一次 end; SysTerminate(code, hand); // 终止进程 return t1; ``` 返回: ###### dbglocalrunning 用途:返回本地解释器正在运行的任务列表与调用栈信息。 参数:无。 返回:任务信息数组(包含 StartInfo/CallStack)。 范例 在本地脚本中运行下面代码: ```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)))) ###### dbglocalcancel 用途:根据任务 ID 终止本地运行中的任务。 参数: 返回:成功返回 1,失败返回 0。 范例 ```tsl tasks := dbglocalrunning(); task_id_hex := tasks[0]["StartInfo"]["id"]; task_id := StrToInt("0x" + task_id_hex); return dbglocalcancel(task_id); ``` ###### SysThreadSelf 用途:获取当前线程 ID(Linux 下为 pthread_t)。 参数:无。 返回:线程 ID(整数)。 范例 在客户端中,本地执行如下代码: ```tsl return SysThreadSelf(); // 返回值:线程ID,如11000 ``` 通过cmd查看天软客户端进程与线程,结果如下: ###### syslinuxkrnlclosemutex 用途:关闭并清理指定互斥量(Linux),用于移除互斥相关的系统信号量与临时文件。 参数: 返回:成功返回 1,失败返回 0。 范例 ```tsl return syslinuxkrnlclosemutex("ts_mutex_demo", 0); ``` ###### SysSetThreadPriority 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:设置当前线程优先级 ```tsl ret := SysSetThreadPriority(1); if ret = 0 then return 1; else return "设置线程优先级失败!"; ``` 结果:返回1,设置成功。 范例02:设置指定线程优先级 ```tsl // 创建函数指针 c := makeinstance(thisfunction(FuncPos), "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 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例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 "获取线程优先级失败!"; ``` ###### SysSetProcessPriority 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:设置当前进程优先级 ```tsl ret := SysSetProcessPriority(32); if ret = 0 then return 1; else return "设置进程优先级失败!"; ``` 结果:返回1,设置成功。 范例02:设置指定线程优先级 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysSetProcessPriority(32, 2932); if ret = 0 then return 1; else return "设置进程优先级失败!"; ``` 结果:返回1,设置成功。 ###### SysGetProcessPriority 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取当前进程优先级 ```tsl ret := SysGetProcessPriority(pri); if ret = 0 then return pri; else return "获取进程优先级失败!"; ``` 范例02:获取指定线程优先级 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysGetProcessPriority(pri, 2932); if ret = 0 then return pri; else return "获取进程优先级失败!"; ``` ###### SysGetProcessList 用途:进程相关函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl ret := SysGetProcessList(); if ret <> 0 then return ret; else return "当前进程列表信息失败!"; ``` 部分结果如下: ###### SysGetProcessListw 用途:进程相关函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl ret := SysGetProcessListw(); if ret <> 0 then return ret; else return "当前进程列表信息失败!"; ``` 部分结果如下: ###### SysGetProcessNamePath 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取指定进程路径 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysGetProcessNamePath(2932); if ret then return ret; else return "获取指定进程路径失败!"; ``` ###### SysGetProcessNamePathw 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取指定进程路径 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysGetProcessNamePathw(2932); if ret then return ret; else return "获取指定进程路径失败!"; ``` ###### SysGetProcessCmdLine 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取指定进程的cmd执行命令 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysGetProcessCmdLine(2932); if ret then return ret; else return "获取指定进程执行命令失败!"; ``` ###### SysGetProcessCmdLinew 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取指定进程的cmd执行命令 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysGetProcessCmdLinew(2932); if ret then return ret; else return "获取指定进程路径失败!"; ``` ###### SysSetThreadName 用途:设置线程名称(Linux 仅支持当前线程)。 参数: 返回:成功返回 0,失败返回非 0。 范例 范例01:设置当前线程名称 ```tsl ret := SysSetThreadName("TinySoft"); if ret = 0 then return 1; else return "设置线程名称失败!"; ``` 结果:返回1,设置成功。 范例02:设置指定线程名称 ```tsl // 创建函数指针 c := makeinstance(thisfunction(FuncPos), "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,设置成功。 ###### SysGetThreadName 用途:获取线程名称。 参数: 返回:线程名称字符串;失败返回 nil 或空串。 范例 范例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 用途:进程相关函数相关函数。 参数:无。 返回:处理后的结果值。 范例 范例01:获取当前进程内的线程列表 ```tsl ret := SysGetThreads(); if istable(ret) then return ret; else return "获取进程内的线程列表失败!"; ``` 部分结果截图如下: 范例02:获取指定进程内的线程列表 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysGetThreads(2932); if istable(ret) then return ret; else return "获取进程内的线程列表失败!"; ``` ###### SysPPid 用途:进程相关函数相关函数。 参数:无。 返回:处理后的结果值。 范例 范例01:获取当前进程的父进程ID ```tsl ret := SysPPid(); if ret then return ret; else return "获取进程的父进程ID失败!"; ``` 范例02:获取指定进程的父进程ID 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysPPid(28848); if ret then return ret; else return "获取进程的父进程ID失败!"; ``` ###### SysGetSubProcesses 用途:进行字符串提取或替换处理。 参数:无。 返回:处理后的结果值。 范例 范例01:获取当前进程的子进程列表 ```tsl ret := SysGetSubProcesses(); if istabel(ret) then return ret; else return "获取进程的子进程列表失败!" ``` 范例02:获取指定进程的子进程列表 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysGetSubProcesses(2932); if istabel(ret) then return ret; else return "获取进程的子进程列表失败!" ``` ###### SysKill 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:终止指定进程 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysKill(2932); if ret then return ret; else return "获取进程的子进程列表失败!" ``` 结果:返回1,任务管理器显示如下 ###### SysPidOfTid 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取当前线程所属进程 ```tsl tid := SysThreadId(); // 获取当前线程ID ret := SysPidOfTid(tid); if ret then return ret; else return "获取线程所属进程ID失败!" ``` ###### SysPidOfHandle 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例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 用途:进程相关函数相关函数。 参数: 返回:处理后的结果值。 范例01:根据进程ID获取进程句柄 打开记事本,在任务管理器中查找对应进程ID: ```tsl ret := SysHandleOfPid(35880); if ret then return ret; else return "根据进程ID获取进程句柄失败!" ``` ##### 本地资源相关函数 ###### 内容 - SysExecName - PluginPath - FileInfo - Getlogicdrive - GetDeviceFree - Getdeviceinfo - Createlink - Realpath - Sysclientinfo ###### SysExecName 用途:获取当前执行程序的完整路径。 参数:无。 返回:程序路径字符串。 范例 客户端中本地执行 ```tsl return rdo2 SysExecName(); ``` 返回:C:\Program Files\Tinysoft\AnalyseNG.NET\TSExpert.exe 本地解析器中运行 ```tsl echo SysExecName(); ``` 打印信息:C:\Program Files\Tinysoft\AnalyseNG.NET\TSL.exe ###### PluginPath 用途:获取插件目录路径。 参数:无。 返回:插件路径字符串。 范例 客户端中本地执行 ```tsl return rdo2 PluginPath(); ``` 返回:C:\Program Files\Tinysoft\AnalyseNG.NET\Plugin\ ###### FileInfo 用途:本地资源相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取本地TSL.exe文件的基本信息 ```tsl path := "D:\\Program Files\\Analyse.NET\\TSL.exe"; return rdo2 FileInfo("", path); ``` 范例02:获取本地已被链接的txt文件信息 ```tsl path := "D:\\test\\test.txt"; return rdo2 FileInfo("", path); ``` ###### Getlogicdrive 用途:本地资源相关函数相关函数。 参数:无。 返回:处理后的结果值。 范例 ```tsl return rdo2 Getlogicdrive(); // 有C、D盘,结果为12,即0b1100 ``` ###### GetDeviceFree 用途:本地资源相关函数相关函数。 参数: 返回:处理后的结果值。 范例 ```tsl return rdo2 GetDeviceFree("", "C:/"); ``` ###### Getdeviceinfo 用途:本地资源相关函数相关函数。 参数: 返回:处理后的结果值。 范例获取C盘的信息 ```tsl return rdo2 Getdeviceinfo("", "C:/"); ``` ###### Createlink 用途:本地资源相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:创建硬链接 ```tsl path := "D:\\test\\test.txt"; // 已经存在的文件 return rdo2 Createlink("D:\\test\\txt", path, 1); // 创建一个硬链接 ``` 结果:创建链接成功,返回1 范例02:创建软链接 ```tsl path := "D:\\test\\test.txt"; // 已存在的文件 return rdo2 Createlink("D:\\test\\txt", path, 0); // 创建一个软链接 ``` 结果:链接成功,返回1 ###### Realpath 用途:本地资源相关函数相关函数。 参数: 返回:处理后的结果值。 范例 范例01:获取文件的真实路径 ```tsl path := "D:\\test\\test.txt"; return rdo2 Realpath(path); ``` 范例02:获取软链接的真实路径 ```tsl path := "D:\\Links\\soft\\s2"; return rdo2 Realpath(path); ``` 范例03:获取硬链接的真实路径 ```tsl path := "D:\\Links\\hard\\h1"; return rdo2 Realpath(path); ``` ###### Sysclientinfo