使用Powershell和Word SaveAs()的麻烦 [英] Troubles using Powershell and Word SaveAs()

查看:375
本文介绍了使用Powershell和Word SaveAs()的麻烦的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从网上的示例中,我已将此脚本拼凑在一起,希望将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()

解决方案

为什么要求打开只读

您正在使用Microsoft Word COM对象,

如果不正确关闭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)

找到了类型不匹配错误的答案这里

From examples on the net, I have cobbled together this script which I hope will save Word .doc files as plainText. It does not.

First, the Word window appears when I have given $word.Visible = $False.

Then, a dialog appears asking if I want to open a read-only copy. No one else has the document open. Why is it asking.

Finally, the error message says I have a type mismatch. Why is that?

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

Here is the source code for the script.

$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()

解决方案

Why is it asking to open read-only

You are using the Microsoft Word COM object,

COM objects are notorious for causing issues if you do not close them properly. In you script calling $word.quit wont close the word.exe process in most cases.

You are getting the error that the document is open because a process from a previous script run has not been closed. You might have clicked stop before the script got to $word.quit() of might have just not quit.

Save all your work and try Get-Process WINWORD | stop-Process -force This will kill all open word processes on your machine. I bet you it will work after that. But you haven't solved the problem of the script leaving the word doc open. Try adding adding this to the end of your script:

$word.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word)
Remove-Variable word

Its how I kill COM object processes and it has never failed to stop a IE com object process, Should work the same for Word.

Why is there a type mismatch

You need to have the library loaded in powershell:

[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Word") | Out-Null

You need to change your .SaveAs to change the filepath to system.object rather than system.string It was a change made in .net 4.0 apparently

$opendoc.SaveAs([ref][system.object]$name,[ref]$saveFormat)

Found the answer to the type mismatch error HERE

这篇关于使用Powershell和Word SaveAs()的麻烦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆