//batch 批处理 import fsys.file; import process.popen; namespace process{ class batch{ ctor( script,ownerArgs,workDir ){{ var tempFile = self.loadcode(script,ownerArgs); this = ..process.popen("cmd.exe",..table.append({"/c",tempFile.path},ownerArgs),{ workDir = workDir : "/"; }) this.codepage = tempFile.codepage; this.beforeClose = function(){tempFile.delete();} }} } batch.loadcode = function(script,ownerArgs){ var err; if( (#script < 0x410/*_MAX_PATH_U8*/ ) && ..string.endsWith(script,".aardio",true) ){ script,err = ..string.loadcode( script ,ownerArgs); } else { if( (#script < 0x410/*_MAX_PATH_U8*/ ) && ( ..io.exist(script) || ..io.localpath(script))){ script = ..string.load(script); } script = ..string.trim(script); if(!..string.startsWith(script,"?>")){ script = "?>" + script; } script,err = ..string.loadcode( script ,ownerArgs); } if(!script) error(err,2); var codepage = 65001; if(!..string.match(script,"^\s*@?chcp\s+65001")){ //HKEY_CURRENT_USER\Console\%SystemRoot%_System32_cmd.exe > CodePage //codepage = tonumber(..process.popen.cmd("chcp").readAll("\d+")); codepage = ::Kernel32.GetConsoleCP();//这里用 chcp 去获取意义不大。 if(..string.isUtf8(script)) { if( codepage != 65001 ) script = ..string.fromto(script,65001,codepage); } else { if( codepage != ::Kernel32.GetACP() ) { //在现代程序中这种可能性基本可以忽略 script = ..string.fromto(script,::Kernel32.GetACP(),codepage); } } } script = ..string.crlf(script); //必须用 \r\n 换行 var tempFile = ..fsys.file.temp(".bat",true); tempFile.write(script); tempFile.write('\r\n\r\n@echo off\r\ndel %0\r\n'); tempFile.close(); tempFile.codepage = codepage; return tempFile; } batch.wow64 = function(...){ return ..fsys.wow64.disableRedirection(lambda(...) batch(...),...) } batch.execute = function(script,ownerArgs,workDir,showCmd=0,hwnd){ var tempFile = batch.loadcode(script,ownerArgs); //::Kernel32.MoveFileEx(tempFile.path,null,4/*_MOVEFILE_DELAY_UNTIL_REBOOT*/); return ..process.execute(tempFile.path,,,showCmd,workDir : "/",hwnd); } } /**intellisense() process.batch = 用于加载批处理代码,支持使用 aardio 模板语法嵌入 aardio 代码 process.batch( = 创建批处理管道进程。\n用于加载批处理代码,支持使用 aardio 模板语法嵌入 aardio 代码\n优先调用 64 位命令请改为 process.batch.wow64 process.batch(.(script,ownerArgs,workDir) = - 参数 @script 可以是批处理脚本或批处理文件,支持资源文件,\n支持使用 aardio 模板语法嵌入 aardio 代码。\n批处理代码会使用自动生成的临时文件加载执行,对象释放时自动删除临时文件。\n- 可选用 @ownerArgs 指定传递给 aardio 模板代码的 owner 参数,\n@ownerArgs 的数组成员传递给批处理作为启动参数,可用 `%1` `%2` ...接收。\n- 可选用 @workDir 指定工作目录,默认为应用程序目录 process.batch.wow64( = 创建批处理管道进程,\n禁用64位文件与注册表重定向,\n在64位系统会返回64位进程,兼容32位系统,\n用于加载批处理代码,支持使用 aardio 模板语法嵌入 aardio 代码 process.batch.wow64(.(script,ownerArgs,workDir) = @script 参数可以是批处理脚本或批处理文件,支持资源文件,\n支持使用 aardio 模板语法嵌入 aardio 代码,\n批处理代码会使用自动生成的临时文件加载执行,对象释放时自动删除临时文件,\n可选用 @ownerArgs 指定传递给 aardio 模板代码的 owner 参数,\n@ownerArgs 的数组成员传递给批处理作为启动参数,可用 `%1` `%2` ...接收。\n可选用 @workDir 指定工作目录,默认为应用程序目录 process.batch() = !process_popen. process.batch.wow64() = !process_popen. process.batch.execute( = 运行批处理代码,支持使用 aardio 模板语法嵌入 aardio 代码。\n批处理代码会使用自动生成的临时文件加载执行\n在批处理尾部会自动添加 `del %0` 以删除临时的批处理文件。\nprocess.batch.execute 不会像 process.batch 那样负责删除临时批处理文件,\n因此批处理代码如果提前执行 EXIT 命令则应当自行调用 `del %0` 。\n\nprocess.batch.execute 在运行批处理以后立即返回,\n不会像 process.batch 那样创建并返回进程管道对象。\n\n这个函数可以用于在退出进程后删除 EXE 自身或运行时占用的目录或文件,示例:\n~~~aardio\nprocess.batch.execute(`:loop\ndel /q ""\nif exist "" goto loop`)\n~~~ process.batch.execute(.(script,ownerArgs,workDir,showCmd,hwnd) = - 参数 @script 可以是批处理脚本或批处理文件,支持资源文件,\n支持使用 aardio 模板语法嵌入 aardio 代码。\n- 可选用 @ownerArgs 参数指定aardio 模板代码可以调用的 owner 参数,\n@ownerArgs 的数组成员传递给批处理作为启动参数,可用%1 %2 ...接收。\n- 参数 @workDir 指定工作目录,可省略,默认为应用程序目录\n- 参数 @showCmd 可省略,默认为 `0/*_SW_HIDE*/`,也就是隐藏批处理窗口。\n- 参数 @hwnd 用于指定所有者窗口句柄,可省略。 end intellisense**/ //@guide [aardio + 批处理混合编程指南](doc://library-guide/std/process/batch.md) /**details(aardio批处理模板语法) [aardio 模板语法](doc://language-reference/templating/syntax.md) 批处理代码中aardio代码必须置于 内部,类似 PHP 的模板语法, 但是要注意与PHP的区别是,aardio规定开始标记 之外的部分解析为: print("批处理代码") 以调用全局函数print输出批处理代码。 print允许接收多个参数,并且对每个参数调用tostring()转换为字符串。 可以使用 输出文本,该代码的作用类似于 print( 表达式 ) , 下面的写法也是允许的 批处理文件应当并且建议以 UTF-8 编码保存,process.batch 会自动转换为 ANSI 编码执行。 end details**/