使用 Powershell 和 Word SaveAs() 时出现问题
Troubles using Powershell and Word SaveAs()
根据网上的例子,我拼凑了这个脚本,我希望它能将 Word .doc 文件保存为纯文本。它没有。
首先,当我给出 $word.Visible = $False.
时出现单词 window
然后,会出现一个对话框,询问我是否要打开只读副本。没有其他人打开该文档。为什么要问。
最后,错误消息说我的类型不匹配。这是为什么?
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()
为什么要求以只读方式打开
您正在使用 Microsoft Word COM 对象,
COM 对象因不正确关闭而导致问题而臭名昭著。在大多数情况下,在您的脚本中调用 $word.quit
不会关闭 word.exe 进程。
您收到文档打开的错误消息,因为来自先前脚本 运行 的进程尚未关闭。您可能在脚本到达 $word.quit()
之前单击了停止,或者可能只是没有退出。
保存你所有的工作并尝试Get-Process WINWORD | stop-Process -force
这将终止你机器上所有打开的word进程。我敢打赌,在那之后它会起作用。
但是您还没有解决脚本使 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
尼克的回答被标记为答案。这是在这种情况下工作的结果脚本。 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
根据网上的例子,我拼凑了这个脚本,我希望它能将 Word .doc 文件保存为纯文本。它没有。
首先,当我给出 $word.Visible = $False.
时出现单词 window然后,会出现一个对话框,询问我是否要打开只读副本。没有其他人打开该文档。为什么要问。
最后,错误消息说我的类型不匹配。这是为什么?
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()
为什么要求以只读方式打开
您正在使用 Microsoft Word COM 对象,
COM 对象因不正确关闭而导致问题而臭名昭著。在大多数情况下,在您的脚本中调用 $word.quit
不会关闭 word.exe 进程。
您收到文档打开的错误消息,因为来自先前脚本 运行 的进程尚未关闭。您可能在脚本到达 $word.quit()
之前单击了停止,或者可能只是没有退出。
保存你所有的工作并尝试Get-Process WINWORD | stop-Process -force
这将终止你机器上所有打开的word进程。我敢打赌,在那之后它会起作用。
但是您还没有解决脚本使 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
尼克的回答被标记为答案。这是在这种情况下工作的结果脚本。 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