繁体   English   中英

如何避免错误 inline PowerShell script 进程无法访问该文件,因为它正被另一个进程使用?

[英]How can avoid an error inline PowerShell script The process cannot access the file because it is being used by another process?

$signalsciencesAgent= Get-Item -Path "C:\Users\Shamim Reza\Desktop\zipfolderpath\sigsci-agent_latest.msi"
if (!(Test-Path $signalsciencesAgent.FullName)) {
    throw "File '{0}' does not exist" -f $signalsciencesAgent.FullName
}
 
try {
    $windowsInstaller = New-Object -com WindowsInstaller.Installer
    $database = $windowsInstaller.GetType().InvokeMember(
        "OpenDatabase", "InvokeMethod", $Null,
        $windowsInstaller, @($signalsciencesAgent.FullName, 0) 
    )
 
    $q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'"
    $View = $database.GetType().InvokeMember(
        "OpenView", "InvokeMethod", $Null, $database, ($q)
    )
 
    $View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null) 
    $record = $View.GetType().InvokeMember( "Fetch", "InvokeMethod", $Null, $View, $Null ) 
    $signalsciencesagentversion = $record.GetType().InvokeMember( "StringData", "GetProperty", $Null, $record, 1 )


} catch {
    throw "Failed to get MSI file version: {0}." -f $_
}

Finally
{

Remove-Item $signalsciencesAgent

}

上面的脚本我用于查看 .msi 文件版本,它运行良好,但是当我使用另一个命令时,如 Remove-Item 或 Invoke-RestMethod 然后得到这个错误我该如何处理这个错误

    Remove-Item : Cannot remove item C:\Users\Shamim Reza\Desktop\zipfolderpath\sigsci-agent_latest.msi: The process cannot access 
    the file 'C:\Users\Shamim Reza\Desktop\zipfolderpath\sigsci-agent_latest.msi' because it is being used by another process.
    At line:30 char:1
    + Remove-Item $signalsciencesAgent
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : WriteError: (C:\Users\Shamim...gent_latest.msi:FileInfo) [Remove-Item], IOException
        + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand

这是因为文件被锁定。 Menaing 仍然有一个文件句柄。 您需要释放锁。

这并不少见,尽管 PS,而且 Stackoverflow 上有很多关于这个主题的文章(使用搜索框找到它们),以及整个互联网。 使用您最喜欢的搜索引擎找到它们。

PowerShell'因为它正被另一个进程使用'

例如:

因为它正被另一个进程使用:为什么没有无依赖的单行 Powershell 解决方案

$MethodDefinition = @'
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
public static extern bool CopyFile(string lpExistingFileName, string lpNewFileName, bool bFailIfExists);
'@

$Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kernel32' -Namespace 'Win32' -PassThru

# You may now call the CopyFile function

# Copy calc.exe to the user’s desktop

$Kernel32::CopyFile("$($Env:SystemRoot)\System32\calc.exe", "$($Env:USERPROFILE)\Desktop\calc.exe", $False)

移动项:该进程无法访问该文件,因为它正在被另一个进程使用

Function Wait-FileUnlock{
    Param(
        [Parameter()]
        [IO.FileInfo]$File,
        [int]$SleepInterval=500
    )
    while(1){
        try{
           $fs=$file.Open('open','read', 'Read')
           $fs.Close()
            Write-Verbose "$file not open"
           return
           }
        catch{
           Start-Sleep -Milliseconds $SleepInterval
           Write-Verbose '-'
        }
    }
}

如果您不关闭流,您将有一个大的内存泄漏。

这是我构建的一个函数,并在我完成后根据需要调用以释放内容。 当然,这是对所有内容的完全清除/发布,因此,您需要根据需要对其进行调整。

Function Clear-ResourceEnvironment
{
    [CmdletBinding(SupportsShouldProcess)]

    [Alias('cre')]

    Param
    (
        [switch]$AdminCredStore
    )


    # Clear only variables created / used during the session
    Compare-Object -ReferenceObject (Get-Variable) -DifferenceObject $AutomaticVariables -Property Name -PassThru |
    Where -Property Name -ne 'AutomaticVariables' |
    Remove-Variable -Verbose -Force -Scope 'global' -ErrorAction SilentlyContinue
    Remove-Variable -Name AdminCredStore -Verbose -Force -ErrorAction SilentlyContinue

    # Clear only modules loaded during the session
    Compare-Object -ReferenceObject (Get-Module) -DifferenceObject $AutomaticVModules -Property Name -PassThru |
    Where -Property Name -ne 'AutomaticVModules' |
    Remove-Module -Force -ErrorAction SilentlyContinue

    # Clear only Aliases loaded during the session
    Compare-Object -ReferenceObject (Get-Alias) -DifferenceObject $AutomaticAliases -Property Name -PassThru |
    Where -Property Name -ne 'AutomaticAliases' |
    Remove-Alias -Force -ErrorAction SilentlyContinue


    # Clear only functions loaded during the session
    Compare-Object -ReferenceObject (Get-Command -CommandType Function) -DifferenceObject $AutomaticFunctions  -Property Name -PassThru |
    Where -Property Name -ne 'AutomaticFunctions' |
    Remove-Item -Force -ErrorAction SilentlyContinue

    # Clear all PSSessions
    Get-PSSession | 
    Remove-PSSession -ErrorAction SilentlyContinue

    # Clear static credential store, if switch is used
    If ($AdminCredStore)
    {Remove-Item -Path "$env:USERPROFILE\Documents\AdminCredSet.xml" -Force}
    Else
    {
        Write-Warning -Message "
        `n`t`tYou decided not to delete the custom Admin credential store.
        This store is only valid for this host and and user $env:USERNAME"
    }

    Write-Warning -Message "
    `n`t`tRemoving the displayed session specific variable and module objects"

    # Clear instantiate reasource interop
    $null = [System.Runtime.InteropServices.Marshal]::
            ReleaseComObject([System.__ComObject]$Shell)

    # instantiate .Net garbage collection
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM