下面的控制台代码旨在生成输入 PDF 文件 pdfMaster.pdf 的受密码保护的副本,并将其写入与输入文件相同的目录中。当我在 Win10 上运行它时它运行得很好,但在 macOS Ventura 上运行 pdfDoc.close();语句使程序崩溃,并显示以下代码后面的消息。
我想这可能是我试图在Mac系统上创建一个文件,但是如果我注释掉pdfDoc.close();语句,对其后面的 File.WriteAllText 的调用工作正常并正确创建其测试文件。
与该程序关联的所有 dll 和其他文件都位于同一 Mac 目录中,我使用“终端”在该目录中运行我的应用程序。我尝试过同时运行它
dotnet Watermark.dll
和
sudo dotnet Watermark.dll
但结果是一样的。我能想到的就是,要么我在做的事情中遗漏了一些东西,要么 Mac 上的 pdfDoc.close() 或 .net6 正在做一些时髦的事情。
因为我能够使用标准 File.WriteAllText 方法创建文件,所以我想知道 iText7 中是否有某种方法可以将加密产生的字节写入字节数组而不是文件。然后我可以简单地使用 File.WriteAllBytes 将该数组写入文件。
using iText.Kernel.Pdf;
using System.Text;
namespace Watermark
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Watermark!");
PdfReader reader = new PdfReader(@"pdfMaster.pdf");
byte[] userPW = Encoding.ASCII.GetBytes("My");
byte[] ownerPW = Encoding.ASCII.GetBytes("PW");
WriterProperties props = new WriterProperties().
SetStandardEncryption(userPW, ownerPW,
EncryptionConstants.ALLOW_PRINTING,
EncryptionConstants.ENCRYPTION_AES_128 |
EncryptionConstants.DO_NOT_ENCRYPT_METADATA);
PdfWriter writer = new PdfWriter(@"pdfOUT_PW.pdf", props);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
pdfDoc.Close();
File.WriteAllText("pdfOutputTest.pdf", "File.WriteAllText test\n");
}
}
}
这是 macOS 消息:
admin@Macs-Mac watermark % dotnet watermark.dll
realpath(watermark.dll) failed: Operation not permitted
getcwd() failed: Operation not permitted
System.TypeInitializationException: The type initializer for 'Microsoft.DotNet.Cli.Parser' threw an exception.
---> System.TypeInitializationException: The type initializer for 'Microsoft.DotNet.Cli.AddCommandParser' threw an exception.
---> System.UnauthorizedAccessException: Access to the path is denied.
---> System.IO.IOException: Operation not permitted
--- End of inner exception stack trace ---
at Interop.Sys.GetCwdHelper(Byte* ptr, Int32 bufferSize)
at Interop.Sys.GetCwd()
at System.IO.Directory.GetCurrentDirectory()
at Microsoft.DotNet.Cli.CommonOptions.DefaultToCurrentDirectory[T](Argument`1 arg)
at Microsoft.DotNet.Cli.AddCommandParser..cctor()
--- End of inner exception stack trace ---
at Microsoft.DotNet.Cli.Parser..cctor()
--- End of inner exception stack trace ---
at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient)
at Microsoft.DotNet.Cli.Program.Main(String[] args)
如果未指定路径,显然 pdfDoc.close 会尝试将指定的输出文件写入 macOS 上执行目录以外的其他位置。也许这被记录在某处?经过大量浪费时间和挫折后,我通过指定解决了问题
PdfWriter writer = new PdfWriter(@"./pdfOUT_PW.pdf", props);
而不是
PdfWriter writer = new PdfWriter(@"pdfOUT_PW.pdf", props);
对我来说,这似乎与下面的阅读器代码完全不一致,它假设文件位于执行目录中,而没有在名称前面指定 ./ 。
PdfReader reader = new PdfReader(@"pdfMaster.pdf");