Perl 与 MS Office 2013(32 位)的 Win32::OLE 问题
Issue in Win32::OLE of Perl with MS Office 2013 (32bits)
我有一个使用 Win32::OLE 访问 MS Word 文件的 Perl 脚本。它在 MS Office 2010 上运行良好,但在我更新到 MS Office 2013 32 位后就不行了。
然后我尝试使用最新版本的 ActivePerl,包括 32 位和 64 位。我正在使用 Windows 7 SP1 64 位。
关闭 MS Word 并调用 Win32::OLE->new('Word.Application', 'Quit')
时,错误出现在以下行中:
my $Word = Win32::OLE->GetActiveObject('Word.Application') || Win32::OLE->new('Word.Application', 'Quit');
[2015 年 8 月 13 日更新] 在命令行中添加 Win32::OLE->GetActiveObject('Word.Application') ||
以强调问题与 new
函数
返回的错误如下:
Win32::OLE(0.1709) error 0x800700c1: "%1 is not a valid Win32
application" at C:\script.pl line 52
eval {...} called at C:\script.pl line 52
有趣的是,第52行对应的是注释行
这是整个脚本(出于调试目的注释行之后):
#!perl
#line 15
#======================================================================
# This script takes a Word document as input and generates out of it
# The Rev_x and the proper .pdf, and add the PDF to SVN
#======================================================================
use Win32::OLE qw(in with valof OVERLOAD);
use Win32::OLE::Const 'Microsoft.Word'; # wd constants
use Win32::OLE::Variant;
$Win32::OLE::Warn = 3;
my $true = Variant(VT_BOOL, 1);
my $false = Variant(VT_BOOL, 0);
use Getopt::Long;
use File::Spec;
use File::Basename;
my $NoChanges = undef;
exit 1 unless &GetOptions('no-changes', $NoChanges);
$DocFile = $ARGV[0];
$DocFile = "E:/SVN/project-docs/6.7/Common Data/03-Standards/SC-ST-019_STST-SDY.docx";
# $DocFile = "E:/SVN/project-docs/6.7/Common Data/SC-TS-048_TS-TOR-DF.docx";
[ -e $DocFile ] || die "*** Cannot open '$DocFile'\n";
if ( ! File::Spec->file_name_is_absolute($DocFile) ) {
warn "File name is not absolute, trying to fix it\n";
my $abs = File::Spec->rel2abs($DocFile);
warn "Finding: $abs\n";
$DocFile = $abs;
}
## Autoflush
$| = 1;
### opening file: try with "new" function, otherwise use "GetActiveObject"
my $Word = Win32::OLE->GetActiveObject('Word.Application') || Win32::OLE->new('Word.Application', 'Quit');
# print "--- Opening $DocFile\n";
# my $document = $Word->Documents->Open({FileName =>$DocFile, ReadOnly =>$true, ConfirmConversions => 0});
# die "Cannot open '$DocFile'\n" unless defined $document;
# $document->Activate();
# ### Extract revision, increment and date from fields
# my $major = $document->Bookmarks->{Doc_Rev}->Range->{Text};
# $major =~ s/ *FORMTEXT *//;
# my $minor = $document->Bookmarks->{Doc_Incr}->Range->{Text};
# $minor =~ s/ *FORMTEXT *//;
# my $date = $document->Bookmarks->{Doc_Date}->Range->{Text};
# $date =~ s/ *FORMTEXT *//;
# my ($id) = (basename($DocFile) =~ /^([A-Z0-9-]+)/);
# print "--- DocID=$id\n";
### Accept all changes
# if ($NoChanges = 1) {
# $Word->ActiveDocument->{TrackRevisions} = $false;
# $Word->WordBasic->AcceptAllChangesInDoc();
# }
# ### Setting normal view to update fields
# $Word->ActiveWindow->ActivePane->View->{Type} = wdNormalView;
# my $selection = $Word->Selection();
# $selection->WholeStory();
# $selection->Fields->Update();
# ### Back to print view & print
# $Word->ActiveWindow->ActivePane->View->{Type} = wdPrintView;
# ### Build PDF filepath
# my $pdf = $DocFile;
# $pdf =~ s/[.]docx?$/.pdf/;
# $pdf =~ s/[.]rtf$/.pdf/;
# $pdf =~ s/$id/$id-$major-$minor/;
# print "PDF = $pdf\n";
# print "--- Printing ";
# $Word->ActiveDocument->ExportAsFixedFormat({ OutputFileName => $pdf,
# ExportFormat => wdExportFormatPDF,
# OpenAfterExport => $false,
# IncludeDocProps => $true,
# OptimizeFor => wdExportOptimizeForPrint,
# CreateBookmarks => wdExportCreateHeadingBookmarks});
# while ( $Word->BackgroundPrintingStatus() > 0 ) {
# print ".";
# sleep 1;
# }
# print "\n";
# $document->Close(wdDoNotSaveChanges);
我在 Whosebug、Perlmonks 等中搜索了信息,但没有找到任何相关信息。
我应该如何修改我的代码才能使其工作。
谢谢
显然,问题出在我的机器上。
Win32::OLE->new
功能在我的电脑上似乎不起作用(但在 Windows 8 下的另一台装有相同版本 MS Office 的计算机上可以使用)。
解决方法是在使用函数 GetActiveObject
之前强制手动打开 MS Word。
我更新的代码如下所示:
### opening file: try with "GetActiveObject" function, otherwise try with "new" function
my $Word;
eval {
$Word = Win32::OLE->GetActiveObject('Word.Application')
|| Win32::OLE->new('Word.Application', 'Quit');
};
if ($@) {
#MS Word shall be opened manually
print "Please open MS Word manually before continuing\n";
print "...Press ENTER to continue...\n";
<STDIN>;
$Word = Win32::OLE->GetActiveObject('Word.Application','Quit');
}
希望对您有所帮助。
我有一个使用 Win32::OLE 访问 MS Word 文件的 Perl 脚本。它在 MS Office 2010 上运行良好,但在我更新到 MS Office 2013 32 位后就不行了。
然后我尝试使用最新版本的 ActivePerl,包括 32 位和 64 位。我正在使用 Windows 7 SP1 64 位。
关闭 MS Word 并调用 Win32::OLE->new('Word.Application', 'Quit')
时,错误出现在以下行中:
my $Word = Win32::OLE->GetActiveObject('Word.Application') || Win32::OLE->new('Word.Application', 'Quit');
[2015 年 8 月 13 日更新] 在命令行中添加 Win32::OLE->GetActiveObject('Word.Application') ||
以强调问题与 new
函数
返回的错误如下:
Win32::OLE(0.1709) error 0x800700c1: "%1 is not a valid Win32 application" at C:\script.pl line 52
eval {...} called at C:\script.pl line 52
有趣的是,第52行对应的是注释行
这是整个脚本(出于调试目的注释行之后):
#!perl
#line 15
#======================================================================
# This script takes a Word document as input and generates out of it
# The Rev_x and the proper .pdf, and add the PDF to SVN
#======================================================================
use Win32::OLE qw(in with valof OVERLOAD);
use Win32::OLE::Const 'Microsoft.Word'; # wd constants
use Win32::OLE::Variant;
$Win32::OLE::Warn = 3;
my $true = Variant(VT_BOOL, 1);
my $false = Variant(VT_BOOL, 0);
use Getopt::Long;
use File::Spec;
use File::Basename;
my $NoChanges = undef;
exit 1 unless &GetOptions('no-changes', $NoChanges);
$DocFile = $ARGV[0];
$DocFile = "E:/SVN/project-docs/6.7/Common Data/03-Standards/SC-ST-019_STST-SDY.docx";
# $DocFile = "E:/SVN/project-docs/6.7/Common Data/SC-TS-048_TS-TOR-DF.docx";
[ -e $DocFile ] || die "*** Cannot open '$DocFile'\n";
if ( ! File::Spec->file_name_is_absolute($DocFile) ) {
warn "File name is not absolute, trying to fix it\n";
my $abs = File::Spec->rel2abs($DocFile);
warn "Finding: $abs\n";
$DocFile = $abs;
}
## Autoflush
$| = 1;
### opening file: try with "new" function, otherwise use "GetActiveObject"
my $Word = Win32::OLE->GetActiveObject('Word.Application') || Win32::OLE->new('Word.Application', 'Quit');
# print "--- Opening $DocFile\n";
# my $document = $Word->Documents->Open({FileName =>$DocFile, ReadOnly =>$true, ConfirmConversions => 0});
# die "Cannot open '$DocFile'\n" unless defined $document;
# $document->Activate();
# ### Extract revision, increment and date from fields
# my $major = $document->Bookmarks->{Doc_Rev}->Range->{Text};
# $major =~ s/ *FORMTEXT *//;
# my $minor = $document->Bookmarks->{Doc_Incr}->Range->{Text};
# $minor =~ s/ *FORMTEXT *//;
# my $date = $document->Bookmarks->{Doc_Date}->Range->{Text};
# $date =~ s/ *FORMTEXT *//;
# my ($id) = (basename($DocFile) =~ /^([A-Z0-9-]+)/);
# print "--- DocID=$id\n";
### Accept all changes
# if ($NoChanges = 1) {
# $Word->ActiveDocument->{TrackRevisions} = $false;
# $Word->WordBasic->AcceptAllChangesInDoc();
# }
# ### Setting normal view to update fields
# $Word->ActiveWindow->ActivePane->View->{Type} = wdNormalView;
# my $selection = $Word->Selection();
# $selection->WholeStory();
# $selection->Fields->Update();
# ### Back to print view & print
# $Word->ActiveWindow->ActivePane->View->{Type} = wdPrintView;
# ### Build PDF filepath
# my $pdf = $DocFile;
# $pdf =~ s/[.]docx?$/.pdf/;
# $pdf =~ s/[.]rtf$/.pdf/;
# $pdf =~ s/$id/$id-$major-$minor/;
# print "PDF = $pdf\n";
# print "--- Printing ";
# $Word->ActiveDocument->ExportAsFixedFormat({ OutputFileName => $pdf,
# ExportFormat => wdExportFormatPDF,
# OpenAfterExport => $false,
# IncludeDocProps => $true,
# OptimizeFor => wdExportOptimizeForPrint,
# CreateBookmarks => wdExportCreateHeadingBookmarks});
# while ( $Word->BackgroundPrintingStatus() > 0 ) {
# print ".";
# sleep 1;
# }
# print "\n";
# $document->Close(wdDoNotSaveChanges);
我在 Whosebug、Perlmonks 等中搜索了信息,但没有找到任何相关信息。
我应该如何修改我的代码才能使其工作。
谢谢
显然,问题出在我的机器上。
Win32::OLE->new
功能在我的电脑上似乎不起作用(但在 Windows 8 下的另一台装有相同版本 MS Office 的计算机上可以使用)。
解决方法是在使用函数 GetActiveObject
之前强制手动打开 MS Word。
我更新的代码如下所示:
### opening file: try with "GetActiveObject" function, otherwise try with "new" function
my $Word;
eval {
$Word = Win32::OLE->GetActiveObject('Word.Application')
|| Win32::OLE->new('Word.Application', 'Quit');
};
if ($@) {
#MS Word shall be opened manually
print "Please open MS Word manually before continuing\n";
print "...Press ENTER to continue...\n";
<STDIN>;
$Word = Win32::OLE->GetActiveObject('Word.Application','Quit');
}
希望对您有所帮助。