【发布时间】:2021-01-12 23:42:30
【问题描述】:
我想使用 WScript.Shell 从 VBA 执行 PowerShell 命令
这是发送到 WScript.Shell 的字符串:
Powershell -ExecutionPolicy Bypass -Command $FilesInPathway = get-childitem -path "C:\Users\Me\Desktop\NewFolder" -recurse -attributes !directory; foreach ($file in $FilesInPathway){$tempName = $file.name; $tempName = $tempName.replace(".TXT",".txt"); Rename-Item $file.fullname $tempName}
这是我要执行的 PowerShell 命令。请注意,此命令确实在 PowerShell 中成功执行。
$FilesInPathway = get-childitem -path "C:\Users\Me\Desktop\NewFolder" -recurse -attributes !directory; foreach ($file in $FilesInPathway){$tempName = $file.name; $tempName = $tempName.replace(".TXT",".txt"); Rename-Item $file.fullname $tempName}
不获取执行 PowerShell 命令时出现问题的信息,但命令未执行且文件未重命名。 Msgbox 不返回任何信息。空白表格。希望避免切换到 PowerShell 脚本或使用 DIR 和 NAME 编写此脚本。
strCommand = "Powershell -ExecutionPolicy Bypass -Command $FilesInPathway = get-childitem -path " & """" & dataPacket.filePath & """" & " -recurse -Attributes !Directory; foreach ($file in $FilesInPathway){$tempName = $file.name; $tempName = $tempName.replace(" & """" & dataPacket.stringOld & """" & "," & """" & dataPacket.stringNew & """" & "); Rename-Item $file.fullname $tempName}"
Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(strCommand)
strOutput = WshShellExec.StdOut.ReadAll
MsgBox strOutput
更新我
新命令确实会遍历目录树并返回该树中正确数量的文件。一定是我传递的 foreach 函数没有执行。但是当我直接在 Powershell 中运行 debug.print 版本的字符串时,它执行得很好——所有文件都被重命名了。
strCommand = "Powershell $FilesInPathway = get-childitem -path " & """" & dataPacket.filePath & """" & " -recurse -attributes !directory; $FilesInPathway.count"
Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(strCommand)
Do While WshShellExec.Status = 0
Application.Wait (Now() + TimeValue("0:00:01"))
Loop
strOutput = WshShellExec.StdOut.ReadAll
MsgBox strOutput
传递给 WshShell 的字符串:
Powershell $FilesInPathway = get-childitem -path "C:\Users\Me\Desktop\NewFolder" -recurse -attributes !directory; $FilesInPathway.count
传递给 PowerShell 的字符串:
$FilesInPathway = get-childitem -path "C:\Users\Me\Desktop\NewFolder" -recurse -attributes !directory; $FilesInPathway.count
注意,我尝试使用 StdIn.Write 方法隔离命令,但出现错误。
WshShellExec.StdIn.Write "$FilesInPathway.count"
更新 II
使用声明的类型或枚举运行 Shell() 可能会生成恶意宏警告并杀死 excel 应用程序?没有隔离导致这种情况的代码。
如果命令中包含-noexit,以下将进入无限循环 在 WshShellExec.Status = 0 时执行 Application.Wait (Now() + TimeValue("0:00:01")) 循环
回答
当然,这将是一个语法问题。需要将 Replace 方法的参数用 ' ' 括起来。如果文件路径包含空格,它也需要带有“ ”的附件。如果直接输入 PowerShell,带有“”的附件可以正常工作。所以命令是:
strCommand = "Powershell $FilesInPathway = get-childitem -path " & "'" & dataPacket.filePath & "'" & " -recurse -attributes !directory; foreach ($file in $FilesInPathway){$tempName = $file.name; $tempName = $tempName.replace('" & dataPacket.stringOld & "','" & dataPacket.stringNew & "'); Rename-Item $file.fullname $tempName}"
【问题讨论】:
-
也许你解释一下你想做什么
-
您是从 Word、Excel 等中的宏/vba 调用它吗?尽管你在哪里从 VBA 运行这个?这 [" & """" & cataPacket.filePath & """" & "] 不是我见过的用于变量使用的格式,也不是适当的扩展。如果您正在运行此表单 PowerShell,我很惊讶它完全成功,因为引用的那些是简单的字符串而不是 UNC 路径。然而,ABL(永远在学习)是我的口头禅。
-
returned = WshShell.Run(strCommand, 4, True)失败?尽管 Dir 没有递归选项,但 VBA 已经看到 Loop Through All Subfolders Using VBA 并查看 FSO -
如果您想使用 WScript.Shell,这不是一个答案,但可能会帮助您调试您的 powershell 行。而且,这不是来自 Excel,而是从 Access 模块运行(但 VBA,所以我认为它应该在 Excel 中工作)。我不想通过重命名我自己的文件来进行测试,所以这只是使用豪华会话来列出打开会话的目录下的文件夹。两个示例,一个可能适合您 - 1)将输出写入文件,2)将输出写入屏幕但保持会话打开,以便您可以读取屏幕然后手动关闭它。
-
我不知道降价 - 让我在几分钟内尝试发布可读代码
标签: excel vba powershell wsh