playbook/docs/tsl/syntax_book/function/tsl/resource.md

3914 lines
96 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#### 资源访问函数
##### 内容
- 资源访问函数简介
- 数据库访问函数
- 文件访问函数
- 网络访问以及相关函数
- INI文件处理函数
- 进程相关函数
- 本地资源相关函数
##### 资源访问函数简介
资源访问函数一般仅为TSL本地解析器所支持例如CGIWORD模板的TSL语句以及其他本地TSL语言解析器。
对于服务器运算的金融分析.NET由于资源访问函数基本上都需要访问到服务器上的一些特有资源例如文件访问数据库访问等而因为服务器上的数据库以及文件的保密性这些函数在一般情况不为在线版本的用户开放仅仅只有当用户购买了服务器版本由系统管理员在服务器上为用户开放了之后才可以使用。
##### 数据库访问函数
###### 内容
- ExecSQL
- SQLBeginTrans
- SQLInTrans
- SQLCommit
- SQLRollBack
- SQLErrorMsg
- SQLCloseConn
- 数据库配置
- Openforwardonly模式
###### ExecSQL
用途:数据库访问函数相关函数。
参数arg1arg2arg3arg4按示例顺序传入
返回:处理后的结果值。
范例
范例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模式无法支持此种类型返回参数。
范例04Array DML 方式批量插入数据范例
```tsl
// 获取数据模型
r := TSFL_SQL_GetData(20130101T, 20131231T);
{Insert语句注意下列数据中EndDateStockIDStockNamepricevol是占位符对应param数组中的占位符。与数据库表中列名无关此处没有指定Test的列名按照数据库表中列的顺序给定数据。如需指定列名在Test后带上列名}
s := "insert into Test values(:EndDate,:StockID,:StockName,:price,:vol)";
{插入数据列值:EndDateStockIDStockNamepricevol是占位符
}
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`<br>说明:该语句不能换行 | 同左 |
| Execsql.ini 完整配置 | `[test]`<br>`ConnectStr=Provider=SQLOLEDB.1;Password=testpw;Persist Security Info=True;User ID=testusername;Initial Catalog=test;Data Source=THINKPAD`<br>`permit=local`<br>说明:`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 文件的Sheet3C2单元格。
```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返回值为1code值为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); |
| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 参数 | Sessionsession ID<br>TotalDown整型下载总字节数<br>Downloaded整型已下载总字节数<br>TotalUpload整型上传总字节数<br>Uploaded整型已上传总计字节数 |
| 说明 | 进度回调过程中,下载总字节数,已下载总字节数,上传总字节数,已上传总计字节数等不一定在每一次回调都会变化,<br>因为会间隔一段时间进行进度更新,即便没有发生进度变化。 |
| 返回 | 回调函数的返回值为0表示继续如果返回为非0则结束请求。若提前结束请求时此时GETHTTP等函数的返回值与code值为0 |
header模式的回调函数定义为
| 定义 | function headercallback(session,headerline); |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 参数 | Sessionsession ID<br>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;[<AttachmentName1:String;AttachmentContent1:String>[…<AttachmentNameN:String;AttachmentContentN:String>]][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
用途:获取当前进程 IDPID
参数:无。
返回:进程 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
用途获取当前线程 IDLinux 下为 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