从网上的例子中,我拼凑了这个脚本,希望将Word .doc 文件保存为plainText。它没有。
首先,当我给出$ word.Visible = $ False时,会出现Word窗口。
然后,会出现一个对话框,询问我是否要打开只读副本。没有其他人打开该文件。为什么要问。
最后,错误消息显示我的类型不匹配。那是为什么?
PS H:\d2> .\wl.ps1
Processing : H:\d2\checklists\Extract checklist_20120306.doc
Name is now: H:\d2\checklists\Extract checklist_20120306.txt
Exception calling "SaveAs" with "2" argument(s): "Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))"
At H:\d2\wl.ps1:19 char:5
+ $opendoc.SaveAs([ref]$name.Value,[ref]$saveFormat)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : COMException
以下是脚本的源代码。
$srcfiles = Get-ChildItem -Path . -Recurse -Filter "*.doc*"
$saveFormat = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatText
$word = new-object -comobject word.application
$word.Visible = $False
ForEach ($doc in $srcfiles) {
Write-Host "Processing :" $doc.fullname
$name = Join-Path -Path $doc.DirectoryName -ChildPath $($doc.BaseName + ".txt")
Write-Host "Name is now:" $name
$opendoc = $word.documents.open($doc.FullName)
$opendoc.SaveAs([ref]$name.Value,[ref]$saveFormat)
$opendoc.Close()
$doc = $null
}
$word.quit()
答案 0 :(得分:1)
为什么要求打开只读
您正在使用Microsoft Word COM对象
如果没有正确关闭它们,COM对象会因引发问题而臭名昭着。在您调用$word.quit
的脚本中,在大多数情况下不会关闭word.exe进程。
您收到文档处于打开状态的错误,因为之前脚本运行的进程尚未关闭。您可能在脚本到达$word.quit()
之前点击了停止,可能还没有退出。
保存您的所有工作并尝试Get-Process WINWORD | stop-Process -force
这会终止您计算机上的所有打开文字进程。我打赌你会在那之后工作。
但是你还没有解决脚本留下doc这个词的问题。尝试添加将此添加到脚本的末尾:
$word.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word)
Remove-Variable word
它是如何杀死COM对象进程的,它从来没有停止过IE com对象进程,对于Word应该是一样的。
为什么会出现类型不匹配
您需要在powershell中加载库:
[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Word") | Out-Null
您需要更改.SaveAs以将文件路径更改为system.object而不是system.string 这显然是在.net 4.0中做出的改变
$opendoc.SaveAs([ref][system.object]$name,[ref]$saveFormat)
找到类型不匹配错误HERE
的答案答案 1 :(得分:0)
尼克的回答被标记为答案。这是在这种情况下工作的结果脚本。 cwd必须是要转换的所有 .doc 文件的父目录。
[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Word") | Out-Null
$srcfiles = Get-ChildItem -Path . -Recurse -Filter "*.doc*"
$saveFormat = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatText
$word = new-object -comobject word.application
$word.Visible = $False
ForEach ($doc in $srcfiles) {
Write-Host "Processing :" $doc.fullname
$name = Join-Path -Path $doc.DirectoryName -ChildPath $($doc.BaseName + ".txt")
Write-Host "Name is now:" $name
$word.Visible = $False
$opendoc = $word.documents.open($doc.FullName)
$opendoc.SaveAs([ref][system.object]$name, [ref]$saveFormat)
$opendoc.Close()
$doc = $null
}
$word.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word) | Out-Null
Remove-Variable word