Issue in Win32::OLE of Perl with MS Office 2013 (32bits)

0

I had a Perl script using Win32::OLE to access a MS Word file. It worked fine with MS Office 2010 but does not after I updated to MS Office 2013 32bits.

I have then tried with latest versions of ActivePerl both 32 bits and 64 bits. I am using Windows 7 SP1 64bits.

The error appears in the following line when MS Word is closed and when Win32::OLE->new('Word.Application', 'Quit') is called:

my $Word =  Win32::OLE->GetActiveObject('Word.Application') || Win32::OLE->new('Word.Application', 'Quit');

[Update 13-Aug-2015] Added Win32::OLE->GetActiveObject('Word.Application') || in the command line to emphasize that problem was related to the new function

The error returned is the following:

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

Interestingly, the line 52 corresponds to a commented line enter image description here

This is the entire script (after commenting lines for debug purpose):

#!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);

I have searched information in StackOverflow, Perlmonks, etc. but not found anything relevant.

How shall I modify my code to make it work.

Thanks

perl
winapi
ms-word
ole
asked on Stack Overflow Aug 12, 2015 by Jean-Francois T. • edited Aug 13, 2015 by Jean-Francois T.

1 Answer

1

Apparently, the problem was specific to my machine.

The function Win32::OLE->new seems not to work on my computer (but works on another computer under Windows 8 with the same version of MS Office).

The workaround was to force opening MS Word by hand before using the function GetActiveObject.

The code I have updated looks like that:

### 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');
}

Hope it helps.

answered on Stack Overflow Aug 12, 2015 by Jean-Francois T. • edited Aug 13, 2015 by Jean-Francois T.

User contributions licensed under CC BY-SA 3.0