首页 > 其他分享 >[AHK2] 使用#Include-二

[AHK2] 使用#Include-二

时间:2023-08-23 18:56:17浏览次数:37  
标签:Resolve .. AHK2 使用 Workdir params Path path Include

开始

上一次,我们提到了如何使用#Include,以及使用时应注意的问题,现在我们就来解决这个问题。

如何保证资源路径始终是正确的?

思路

我们仿造nodeJs的Path.resolve(),实现一个ahk的resolve()。
但要注意的一点是:

  • 使用静态变量Workdir代替__dirname

因为我们没有这样一个__dirname变量,只有自己造。

接下来,就是实现各种情况的path拼接了,需要考虑的方面十分多,总结包括以下几点:

  • .开头
  • ..开头
  • 以盘符开头
  • 以路径开头
    • 以绝对路径开头
    • 以相对路径开头

同时,还要考虑多参及分隔符统一的情况。

实现

为解决多参问题,我们先分为无、单参和多参进行处理,先处理简单的,在对付难的。
具体细节我便不再多讲,代码都有完整的注释。

需要注意的是,我算法并不好,所以采用的只是简单的循环判断。不过结果肯定没问题:(

resolve()实现

  ; param: paths
  ; ret:   absolute path --> string
  ; desc:  convert to absolute path
  static Resolve(params*) {
    len := params.Length
    ; 单参,默认以当前目录为基准
    if !len || (len == 1 && (params[1] == '' || params[1] == '.')) { ; 无参,参数为空值及.返回当前目录
      return StrReplace(Path.Workdir, '\', Path.Sep)
    } else if (len == 1) {
      if (params[1] ~= '^\.[\\/]') { ; ./开头,直接去除开头./,再规范化后即可返回
        ; 去除开头的./
        _path := Path.Workdir SubStr(params[1], 2)
        ; 统一分隔符
        _path := StrReplace(_path, '/', '\')
        ; 去除末尾 \
        _path := RTrim(_path, '\')
        ; 规范化
        _path := StrReplace(_path, '\', Path.Sep)
        return _path
      }
      else if (params[1] ~= '^\.\.[\\/]') { ; ../ 开头的单参,连接目录路径后放行
        params[1] := Path.Workdir params[1]
      }
      else if (params[1] ~= '^\.\.$') { ; .. 添加sep后放行
        params[1] := Path.Workdir params[1] Path.Sep
      }
      else { ;无法处理
        return StrReplace(Path.Workdir, '\', Path.Sep)
      }
    }
    ; 多参
    for index, param in params {
      if !param ; 跳过空值
        continue
      if param ~= '^[\\/]' { ; 如果以分隔符开头,则清除先前的路径
        _path := param
      }
      else if (index == 1) ; 第一个参数,不加sep
        _path .= param
      else ; 添加分隔符
        _path .= '\' param
    }
    ; 统一分隔符
    _path := StrReplace(_path, '/', '\')
    ; 替换 ..
    while (_path ~= 'i)\.\.') {
      ; 找到..位置
      subStart := InStr(_path, '..')
      ; 找到..前第二个\位置
      subEnd := InStr(_path, '\', , -(StrLen(_path) - subStart) - 3)
      ; 裁剪出待替换字串
      sub := SubStr(_path, subEnd, subStart - subEnd + 2)
      ; MsgBox subStart '--' subEnd '`n' sub '`n' _path
      _path := StrReplace(_path, sub, '')
      if !sub
        throw Error('invalid param! current path--> ' _path)
    }
    ; 替换 .\
    _path := StrReplace(_path, '.\', '')
    ; 去除末尾 \
    _path := RTrim(_path, '\')
    ; 规范化
    _path := StrReplace(_path, '\', Path.Sep)
    ; 判断是否带盘符,无则添加当前盘符
    if _path ~= 'i)^\w:[\\/]'
      return _path
    ; 判断是否添加全路径
    else if _path ~= '^[\\/]' {
      drive := SubStr(Path.Workdir, 1, 1)
      return drive ':' _path
    }
    else {
      scriptDir := StrReplace(Path.Workdir, '/', Path.Sep)
      scriptDir := StrReplace(Path.Workdir, '\', Path.Sep)
      return scriptDir Path.sep _path
    }
  }

测试

以下是测试用例:

其中,注释为正确结果

if A_LineFile == A_ScriptFullPath {
  MsgBox Path.Resolve() ; C:\Users\u\Desktop\AhkPlanE\utils
  MsgBox Path.Resolve('.') ; C:\Users\u\Desktop\AhkPlanE\utils
  MsgBox Path.Resolve('./') ; C:\Users\u\Desktop\AhkPlanE\utils
  MsgBox Path.Resolve('..') ; C:\Users\u\Desktop\AhkPlanE
  MsgBox Path.Resolve('../') ; C:\Users\u\Desktop\AhkPlanE
  MsgBox Path.Resolve('./abc\') ; C:\Users\u\Desktop\AhkPlanE\utils\abc
  MsgBox Path.Resolve('..\abc\..\def')  ; C:\Users\u\Desktop\AhkPlanE\def
  MsgBox Path.Resolve('C:\Users\u\Desktop\AhkPlanE', '../') ; C:\Users\u\Desktop
  MsgBox Path.Resolve('C:\Users\u\Desktop\AhkPlanE', '../res/light/../abc') ; C:\Users\u\Desktop\res\abc
  MsgBox Path.Resolve('/ic', '../a/b', '.\d') ; C:\a\b\d
  MsgBox Path.Resolve('abc', '/ic', '../a/b', '.\d') ; C:\a\b\d
}

join()实现

另外,顺便增加一个简单的拼接方法。

; param: separator | paths
; ret:   path --> string
; desc:  Connect paths using separator
static Join(sep, params*) {
  for index, param in params
    str .= param . sep
  return SubStr(str, 1, -StrLen(sep))
}

静态变量

; 设置当前目录
static Workdir := '' || A_ScriptDir
static Sep := '/'

其中,Sep为resolve统一后的分隔符。

workdir的使用

回到之前的a、b.ahk例子中,现在a脚本的资源引用需要这样书写:

this.AddPicture('yp h30 w50 vPic', Path.Resolve(Path.Workdir, 'res/light.png'))

以a脚本启动时便需要设置workdir变量:

Path.Workdir := Path.Resolve(A_ScriptDir, '../')
PlanEGui.Show({ theme: 'light' })

而b脚本无需修改。

以此便解决了资源引用的问题,只需手动设置Workdir即可(谁叫我们没有呢XD),同时,Resolve()也可在其他地方使用。由测试用例中可见它的功能还是很强大的。

标签:Resolve,..,AHK2,使用,Workdir,params,Path,path,Include
From: https://www.cnblogs.com/refiz/p/17652532.html

相关文章

  • Unity UGUI的Slider(滑动条)件组的介绍及使用
    UnityUGUI的Slider(滑动条)件组的介绍及使用1.什么是Slider组件?Slider(滑动条)是UnityUGUI中的一种常用UI组件用,于在用户界面中实现滑动选择的功能。通过拖动滑块,用户可以选择一个数值范围的内值。2.Slider组件的工作原理Slider组件由两部分组成:滑动区域和滑块。滑动区域用于......
  • 支持多数据源联合查询的SQL运行引擎sycnany-SQL使用类型注解和类型转换
    使用介绍安装和配置使用自定义函数sycnany-SQL作为SQL运行引擎并不需要提前定义Schema信息,而且很多数据源本身就是无Schema信息的,例如NoSQL数据库MongoDB,所以从数据源查询数据和运行计算默认直接使用输入数据的类型完成查询和计算,此时查询数据或执行计算可能因数据类型不匹配产......
  • [AHK2] 屏幕放大镜
    介绍此脚本源自远古的ahk1,里面甚至使用了IfLess这种语法。但不管怎么说,它是个十分好的脚本,代码精简,效率也好。所以我将它升级到了ahk2版,并对部分内容做提炼,疏通了整个脚本的脉络(老语法实在混乱)。它的作用就是可以放大鼠标下的屏幕,以gui的形式展示出来。效果如下:此外,还有以下......
  • 记录--为什么要使用 package-lock.json?
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助前言随着JavaScript在现代软件开发中的日益重要地位,Node.js生态系统中的npm成为了不可或缺的工具。在npm管理依赖的过程中,package-lock.json文件的作用日益凸显。本文将深入探讨为什么要使用package-lock.json,以及......
  • 使用easyexcel导入62个字段,十万加行数的excel
    使用easyexcel导入62个字段,十万加行数的excel1️⃣准备工作1.版本对应在easyexcel官网的常见问题栏中往下滑找到2.下载jar包maven项目不想多说,在pom.xml文件下,dependcy标签下引入就可以;在web_inf项目下需要手动引入jar包,在mvn中心仓库,下载对应jar包以及所依赖的其他jar包......
  • free命令详细的使用方法
    free-h在下面这些情况下,系统是正常的,不需要担心空闲内存free接近于0已使用内存used接近于total可用内存(free+buffers/cache)占total的20%以上交换分区内存 swap 没有发生改变下面情况说明内存过低,需要注意!可用内存(free+buffers/cache)过低,接近于0的时候交换分区内存占用swapuse......
  • elementUI使用echarts的空气质量地图统计
    准备工作:前端安装:yarninstallecharts 、 yarninstallvue-baidu-map--save前端在public文件夹下的index.html中head标签中加入:<scriptsrc="https://api.map.baidu.com/api?v=2.0&ak=你的AK"></script>其中,key的申请地址:https://lbsyun.baidu.com/apiconsole/k......
  • unity在使用了HybridCLR进行编译时报错
    unity在使用了HybridCLR执行HybridCLR/Generate/All时,一直不成功,提示pleasefirstuse"HybridCLR/Generate/All"后面还有fatalerror:'icalls/mscorlib/System/MonoType.h'filenotfound#include"icalls/mscorlib/System/MonoType.h"每次执行HybridCLR/Gener......
  • shell命令概述 Shell作用:命令解释器 介于操作系统内核与用户之间,负责解释命令行 获得
    shell命令概述Shell作用:命令解释器介于操作系统内核与用户之间,负责解释命令行获得命令帮助内部命令help命令的“--help”选项使用man命令阅读手册页命令行编辑的几个辅助操作Tab键:自动补齐反斜杠“\”:强制换行快捷键Ctrl+U:清空至行首快捷键Ctrl+K:清空至行尾快捷键Ctr......
  • ZLMediaKit实现拉取摄像头(海康协议)编码为H265并使用flv.js播放时提示:FLV:Unsupport
    场景开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rtsp视频流)并使用http-flv网页播放:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130136245按照上面流程进行拉取摄像头的rtsp流并转流使用flv.js播放时提示:DemuxException:type-......