PowerShell+MSI。如何释放打开的数据库?

发布于 2024-12-06 17:13:44 字数 754 浏览 1 评论 0原文

我有 VB 脚本:

.....
Set oInstaller  = CreateObject("WindowsInstaller.Installer")
Set otempDB = oInstaller.OpenDatabase(sMsiFullPathTemp, 1)
.......
Set otempDB = Nothing

在这个字符串中它释放数据库:Set otempDB = Nothing。

我需要制作像这样的 VBS 的 PowerShell 脚本才能与 MSI 一起使用。

PowerShell:

....
function Invoke-Method ($Object, $MethodName, $ArgumentList) {
    return $Object.GetType().InvokeMember($MethodName, 'Public, Instance, InvokeMethod', $null, $Object, $ArgumentList)
}
$oInstaller = New-Object -ComObject WindowsInstaller.Installer
$otempDB = Invoke-Method $oInstaller OpenDatabase  @($tempmsi, 1)

但是我如何在脚本尚未完成工作之前释放 MSI 数据库? 我的意思是: Set otempDB = Nothing

有人可以帮助我吗?

谢谢

I have VB Script:

.....
Set oInstaller  = CreateObject("WindowsInstaller.Installer")
Set otempDB = oInstaller.OpenDatabase(sMsiFullPathTemp, 1)
.......
Set otempDB = Nothing

At this string it releases database: Set otempDB = Nothing.

I need to make PowerShell script like this VBS to work with MSI.

PowerShell:

....
function Invoke-Method ($Object, $MethodName, $ArgumentList) {
    return $Object.GetType().InvokeMember($MethodName, 'Public, Instance, InvokeMethod', $null, $Object, $ArgumentList)
}
$oInstaller = New-Object -ComObject WindowsInstaller.Installer
$otempDB = Invoke-Method $oInstaller OpenDatabase  @($tempmsi, 1)

But how I can release MSI database until script haven't finished work?
I mean something like: Set otempDB = Nothing

Could someone help me with it?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

聚集的泪 2024-12-13 17:13:44

您始终可以将变量分配给 $null:

$otempDB = $null

但是对于 COM 对象,这通常会导致对象被转移到某个地方。更好的方法是显式地释放对象并清理内存:

([System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$otempDB) -gt 0)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

前段时间我在某个地方遇到了一个用于此目的的函数(如果有人知道最初发布此函数的人,请留下评论,我将归因于它)。我几乎每次使用 COM 对象时都会使用它:

function Release-Ref ($ref) {

    ([System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$ref) -gt 0)
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()

}

you can always assign the variable to $null:

$otempDB = $null

However for COM objects this often results in the object just being shuffled off to limbo somewhere. Better is to explicitly relese the object and clean up the memory:

([System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$otempDB) -gt 0)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

Somewhere I came across a function for this some time ago (if someone knows who originally posted this function please leave a comment and I will attribute it). I use it pretty much any time that I work with COM objects:

function Release-Ref ($ref) {

    ([System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$ref) -gt 0)
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文