0

当前使用以下代码搜索目录并将找到的任何 .msi 复制到另一个目录。如果另一个程序正在使用 .msi,我不想复制它。我在 StackExchange 上看到了其他问题,这些问题显示了检查文件是否正在使用的其他方法,但是在Rename-Item命令周围使用 try/catch 块似乎是一个更简单的解决方案。如果脚本无法重命名我想要的项目,请转到$file. $listoffiles我可以让它工作的唯一方法是使用下面列出的代码。但是,我似乎无法按照我想要的方式格式化生成的错误消息,而且似乎-ErrorAction Stop没有必要。如果块中发生错误,try错误不应该只是进入catch块吗?此外,我的错误消息中的 3 个变量中只有 2 个被写入日志文件。

当前代码:

$listofFiles=(Get-ChildItem -Path $outputPath -Filter "*.msi" | where {$_.Name -notlike "*.Context.msi" -and $_.LastAccessTime -gt (Get-Date).AddMinutes(-15)})

foreach ($file in $listofFiles){
    $y = ($file -split ("\\"))
    $msiFolder = $y[4]

    #Tests to see if $file currently in use
    try{
        Rename-Item -Path $file -NewName $file -ErrorVariable renameError -ErrorAction Stop 
    }
    catch{
        "$logTime ERROR Could not copy $msiFolder: $renameError.Exception.Message()" >> $copyLog
        continue
    }   

    #Code that copies files that are not in use.

目前错误显示如下:

02/18/13 13:43:25 ERROR Could not copy  System.Management.Automation.ActionPreferenceStopException: Command execution stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: The process cannot access the file because it is being used by another process.
   at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)
   at System.Management.Automation.StatementListNode.Execute(Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)
   at System.Management.Automation.TryStatementNode.Execute(Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context).Exception.Message()

我希望它看起来像:

02/18/13 13:34:34 ERROR Could not copy ABC_CLIENT: The process cannot access the file because it is being used by another process.

问题

  1. 为什么 $msiFolder 没有出现在日志消息中?
  2. 如何简化错误消息?
  3. 有没有更好的方法来使用 try/catch 块来打破 foreach 循环的迭代?

更新1:

我清除$error并运行:

Rename-Item -Path $file -NewName $file -ErrorAction SilentlyContinue
if (!$?){"$logTime ERROR Could not copy $file: $error[0].Exception.Message()" >> $copyLog}

结果是:

02/18/13 14:52:59 ERROR Could not copy  The process cannot access the file because it is being used by another process.[0].Exception.Message()

为什么$logTime会打印但其他变量没有?

更新 2: 我使用的最终代码:

Rename-Item -Path $file -NewName $file -ErrorAction SilentlyContinue 
if (!$?){
    "$logTime ERROR Could not copy ${msiFolder}: $($error[0].Exception.Message)" >> $copyLog
    continue
}
4

1 回答 1

1

如果要使用 try/catch,则需要将从 Rename-Item 获得的非终止错误转换为终止错误。这就是为什么您需要使用 -ErrorAction Stop 来调用您的 catch 块。但是,您可以通过其他方式执行此操作,例如:

foreach ($file in $listofFiles){
    $y = ($file -split ("\\"))
    $msiFolder = $y[4]

    #Tests to see if $file currently in use
    Rename-Item -Path $file -NewName $file -ErrorVariable renameError -ErrorAction SilentlyContinue
    if (!$?) {
        "$logTime ERROR Could not copy ${msiFolder}: $($error[0].Exception.Message)" >> $copyLog
        continue
    }   

    #Code that copies files that are not in use.
}

自动变量$?指示最后一个命令是否成功。

至于为什么 $msiFolder 没有得到输出,我会检查拆分操作。检查 $y.count 是否 >= 5。

于 2013-02-18T19:05:27.867 回答