Board logo

标题: [问题求助] PowerShell能否实现: 在一个函数中执行参数中的代码 [打印本页]

作者: 5i365    时间: 2022-3-17 07:35     标题: PowerShell能否实现: 在一个函数中执行参数中的代码

实际的情况是这样的, 我需要处理的文件它是一个伪zip文件,  【之所以这么称呼, 是因为这个文件的扩展名不是zip, 但它又可以用zip软件解压缩出来内部的文件, 这种文件在实际工作中经常遇到】

假设它的路径: 定义为变量$path 其值为 C:\Users\Administrator\Desktop\test.map

我需要修改里面的某个文件, 定义为变量$name 其值为 123.txt

怎么修改呢? 我想用一段PS代码修改它, 定义为变量$code 其值如下
sc $name "我是新加的文本"
# 下面可能还会有很多PS代码

修改完后,把$name文件和原来$path中的其它文件重新打包回原文件名+扩展名的文件

如果成功执行返回$true,失败返回$false

以前idwma大侠帮忙处理过一个类似的情况, 贴子链接如下, 期待高手能帮忙完善一下, 提前感谢!
http://www.bathome.net/redirect. ... 1524&pid=251339

示例文件test.map下载 : https://send.cm/d/9UGU
________________________________________________________________________
函数的结构如下:
function unzip_plus($path, $name, $code)
{
        #1首先把$path解压
        #2然后用$code修改$name
        #3最后把$name文件和原来$path中的其它文件重新打包回原文件名+扩展名的文件
        #4如果成功执行返回$true,失败返回$false
}

$path = "C:\Users\Administrator\Desktop\test.map"
$name = "123.txt"
$code = @"
sc $name "我是新加的文本"
# 下面可能还会有很多PS代码
"@

unzip_plus -path $path -name $name -code $code
作者: 5i365    时间: 2022-3-17 07:44

本帖最后由 5i365 于 2022-3-17 07:46 编辑

上面函数的结构中, 对于
#2 还有个情况就是我不想修改$name了, 在$code中, 用命令把它删了, 那么
#3 打包时就不能有$name文件了,  那么要怎么处理?

感觉这是个很好的入门函数定义的例子, 而且还很抽象
作者: idwma    时间: 2022-3-17 15:08

  1. function unzip_plus($path, $name, $code)
  2. {
  3. $shell=New-Object -com shell.application
  4. try{
  5.         #1首先把$path解压
  6. $z="$path.zip"
  7. mv $path $z
  8. $shell.Namespace("$pwd").MoveHere($($shell.NameSpace($(gi $z).fullname).items()|?{$_.name -eq $name}))
  9.         #2然后用$code修改$name
  10. $code|iex
  11.         #3最后把$name文件和原来$path中的其它文件重新打包回原文件名+扩展名的文件
  12. if(test-path $name){$shell.NameSpace($(gi $z).fullname).MoveHere($(gi $name).fullname)}
  13. mv $z $path
  14.         #4如果成功执行返回$true,失败返回$false
  15. return $true
  16. }catch{$false}
  17. }
复制代码

作者: 5i365    时间: 2022-3-17 18:44

本帖最后由 5i365 于 2022-3-17 18:46 编辑

回复 3# idwma


    大侠好, 刚试了下,
生成的文件里面没有那个文本文件了, 好像是没有打包进去,
是否执行成功而显示$true或false, 好像没执行完就显示了

示例文件test.map下载 : https://send.cm/d/9UGU
完整代码如下:
  1. function unzip_plus($path, $name, $code)
  2. {
  3. $shell = New-Object -com shell.application
  4. try
  5. {
  6. #1首先把$path解压
  7. $z = "$path.zip"
  8. mv $path $z
  9. $shell.Namespace("$pwd").MoveHere($($shell.NameSpace($(gi $z).fullname).items() | ?{ $_.name -eq $name }))
  10. #2然后用$code修改$name
  11. $code | iex
  12. #3最后把$name文件和原来$path中的其它文件重新打包回原文件名+扩展名的文件
  13. if (test-path $name) { $shell.NameSpace($(gi $z).fullname).MoveHere($(gi $name).fullname) }
  14. mv $z $path
  15. #4如果成功执行返回$true,失败返回$false
  16. return $true
  17. }
  18. catch { $false }
  19. }
  20. $path = "C:\Users\Administrator\Desktop\test.map"
  21. $name = "123.txt"
  22. $code = @"
  23. sc $name "我是新加的文本"
  24. # 下面可能还会有很多PS代码
  25. "@
  26. unzip_plus -path $path -name $name -code $code
复制代码

作者: 5i365    时间: 2022-3-17 20:25

回复 3# idwma


    能用这里的zip功能吗?
http://www.bathome.net/redirect. ... 1362&pid=250759
作者: idwma    时间: 2022-3-17 20:27

本帖最后由 idwma 于 2022-3-17 20:32 编辑

13行后面加个延时sleep 1
这里的情况在net2.0下不能用那方法,高版本的可以文档里有方法,不通用就不搞了
作者: 5i365    时间: 2022-3-17 20:42

回复 6# idwma


    大侠牛X, 加了延时, 就可以了, 不过要刷新一下, 后缀才会变成.map 可能和我系统有关系, 我现在是双系统, 在win7下试的
作者: 5i365    时间: 2022-3-17 21:13

回复 6# idwma


感觉上面的代码很神奇, 文件先移过去, 最后再移回来,变戏法似的却把文件给解压后又压缩了,
查了一些资料, 把 shell.application对象 在本例用到的方法之解释抽取出来了, 供路过的人参考:
真心感觉处理一些实际问题时, 先找方法或组件的重要性, 有时很复杂的问题, 早就被高手封装成了组件或函数, 我们只要找到它, 给他几个参数就吐出结果来了.
关键还是得多搜索, 多学习, 多实践, 多向前辈请教, 再次感谢 idwma 大侠一直以来的热心帮助

NameSpace 创建和返回指定的文件夹的Folder对象
MoveHere 移动一个项目或项目组到一个文件夹
Items 得到FolderItems对象,表示文件夹内项目的集合

详细参考
https://www.cnblogs.com/yl153/articles/6727211.html
https://docs.microsoft.com/zh-hk ... ell/folder-movehere
作者: 5i365    时间: 2022-3-18 11:07

本帖最后由 5i365 于 2022-3-18 11:21 编辑

回复 3#  


   大侠好, 经过多次测试, $name文件会替换掉脚本相同目录下的同名文件, 所以移到了临时文件夹进行处理, 一些其它细节也有精简, 加了一些注释, 再次感谢!
________________________________________________________________________________________________________
本人所发所有贴子或代码, 路过的大侠,若认为: 含有瑕疵, 需要改进, 可以增强优化精简之处, 请不吝赐教,感激不尽!

  1. #作者: idwma@bathome   #润色: 5i365@bathome.
  2. #理解的要点:
  3. #shell.application对象包含可以直接处理zip文件和伪zip文件的Namespace, MoveHere, Items等方法
  4. #伪zip文件也是zip文件,可以当成zip文件来处理
  5. #zip文件因为在win系统下直接可以像文件夹一样打开浏览,所以将zip文件理解为zip文件夹
  6. function unzip_plus($path, $name, $code)
  7. {
  8.         $shell = New-Object -com shell.application
  9.         try
  10.         {
  11.                 #1用重命名的方法给伪zip文件添加zip扩展名,方便shell.application对象的方法进行处理
  12.                 $z = "$path.zip"
  13.                 ren $path $z
  14.                
  15.                 #2将zip中的要处理的文件移动到临时文件夹
  16.                 # Namespace后的()可理解为:放置要处理的文件的文件夹
  17.                 # MoveHere后的()可理解为:移动到前面文件夹中的要处理的文件
  18.                 $shell.Namespace("$env:TEMP").MoveHere("$z\$name")
  19.                
  20.                 #3 $code代码中的$name变量要替换为要处理文件的实际临时文件夹下的路径
  21.                 $temp_name = "$env:TEMP\$name"
  22.                 $code.Replace('$name', $temp_name) | iex
  23.                
  24.                 #4 如果处理后的文件还存在,就移动回原zip文件夹
  25.                 # 把zip文件理解成一个文件夹,来的更简单
  26.                 if (test-path $temp_name)
  27.                 {
  28.                         $shell.NameSpace("$z").MoveHere($temp_name)
  29.                 }
  30.                
  31.                 #5需要加延时,否则已处理的文件无法移回去原zip文件夹
  32.                 sleep 1
  33.                
  34.                 #6 重命名回zip扩展名
  35.                 ren $z $path
  36.                
  37.                 #7如果成功执行返回$true; 下面的异常则为失败返回$false
  38.                 return $true
  39.         }
  40.         catch { $false }
  41. }
  42. $path = "C:\Users\Administrator\Desktop\test.map"
  43. $name = "123.txt"
  44. $code = @'
  45. ac $name "我是新加的文本"
  46. '@
  47. unzip_plus -path $path -name $name -code $code
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2