4

我正在尝试使用 EBook::Epub 将 html 文件转换为 epub。我写的脚本很简单,像这样:

my $epub = EBook::EPUB->new;
$epub->add_title('title');
$epub->add_author('author');
$epub->add_language('en');
$epub->copy_xhtml("d:/path/to/file.html" , "file.html");
$epub->pack_zip("d:/path/to/file.epub");

当我从命令行运行它时,它工作得很好。但是,我正在尝试将它作为 CGI 脚本部署在 IIS6 服务器上——它在同一台计算机上运行——它失败并显示以下消息:

Can't call method "desiredCompressionLevel" on an undefined value at C:/strawberry/perl/vendor/lib/Archive/Zip/Archive.pm line 252.

我检查了 Archive.pm,第 252 行在子 addFile 中。它使用了三个变量——$fileName、$newName、$compressionLevel——我使用了一些打印语句从第 252 行之前显示它们的值。($compressionLevel 始终为空白)

这是来自命令行,它有效:

filename: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\7QiqzzNiN5/OPS/file.html 
newname: OPS/Advanced8247.html
filename: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\7QiqzzNiN5/OPS/content.opf 
newname: OPS/content.opf
filename: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\7QiqzzNiN5/OPS/toc.ncx 
newname: OPS/toc.ncx
filename: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\DkgiQN_pTq 
newname: META-INF/container.xml

这是来自服务器,它炸弹:

filename: C:\WINDOWS\TEMP\8rxbvOVkKy/OPS/file.html 
newname: OPS/Advanced6575.html
filename: C:\WINDOWS\TEMP\8rxbvOVkKy/OPS/content.opf 
newname: OPS/content.opf
filename: C:\WINDOWS\TEMP\8rxbvOVkKy/OPS/toc.ncx 
newname: OPS/toc.ncx
filename: C:\WINDOWS\TEMP\WqS7fskWi0 
newname: META-INF/container.xml

所以我猜我的问题与临时文件的写入位置有关,但我对服务器和 Archive::Zip 的了解还不够多,无法弄清楚。有任何想法吗?

4

1 回答 1

0

确保写入的临时目录可由运行 IIS 的 IIS 用户(IIS_IUSRS 和/或 IUSR)写入。当您在命令行上运行时,您是以不同的用户身份运行的,该用户可能具有写入 C:\Windows\Temp 的权限。我有一个类似的问题(写入同一个临时目录)并且能够通过将临时目录更改为我的 Web 应用程序的已发布文档根目录更本地的内容来解决该问题,该目录在“属性”>“安全”下已经具有正确的权限。

在我的情况下,我可以在我的脚本中设置环境变量 TMPDIR:

$ENV{TMPDIR} = 'C:\Inetpub\tmp'

并且 C:\Inetpub\tmp 的文件夹权限已更新为可由 IIS_IUSRS 和 IUSR 写入。

这是来自http://metacpan.org/pod/Archive::Zip的片段,其中讨论了临时文件和设置 $ENV{TMPDIR}

Archive::Zip::tempFile( [$tmpdir] )

Create a uniquely named temp file. It will be returned open for read/write. If $tmpdir
is given, it is used as the name of a directory to create the file in. If not given, 
creates the file using File::Spec::tmpdir(). Generally, you can override this choice
using the

    $ENV{TMPDIR}

environment variable. But see the File::Spec documentation for your system. Note that 
on many systems, if you're running in taint mode, then you must make sure that 
$ENV{TMPDIR} is untainted for it to be used. Will NOT create $tmpdir if it doesn't 
exist (this is a change from prior versions!). Returns file handle and name:

    my ($fh, $name) = Archive::Zip::tempFile();
    my ($fh, $name) = Archive::Zip::tempFile('myTempDir');
    my $fh = Archive::Zip::tempFile();  # if you don't need the name
于 2011-06-02T16:15:32.460 回答