实现效果:
问题点:Adobe PDF Reader中并没有可以直接旋转的方法
LoadFile加载文件,文件URL地址GotoFirstPage到第一页GotoLastPage到最后一页GotoPreviousPage上一页GotoNextPape下一页SetCurrentpage到指定页Setshowscrollbars设置是否显示 Acrobat Reader的滚动条。带一个参数,该参数设为0时不显示滚动条,设为1时显示滚动条SetshowToolbar设置是否显示 Acrobat Reader的工具栏。带一个参数,该参数设为时不显示,设为1时显示。Setview设置显示效果。Fit:适应窗口大小; FitH:适合宽度setZoom设置文件的显示比例;默认是100解决办法:引入PdfiumViewer旋转PDF并保存替换当前的文件。
- /// <summary>
- /// 旋转保存PDF文件并释放文件锁定
- /// </summary>
- /// <param name="axControl"></param>
- /// <param name="filePath"></param>
- /// <param name="pdfRotation"></param>
- /// <returns></returns>
- public bool SafeSavePdfWithRelease(AxAcroPDFLib.AxAcroPDF axControl, string filePath, PdfRotation pdfRotation)
- {
- const int MAX_RETRY = 3;
- const int RETRY_DELAY = 500;
- for (int attempt = 0; attempt < MAX_RETRY; attempt++)
- {
- try
- {
- // 步骤1:创建临时副本
- string tempPath = Path.GetTempFileName().Replace(".tmp", ".pdf");
- File.Copy(filePath, tempPath, true);
- // 步骤2:使用内存流操作
- using (var ms = new MemoryStream(File.ReadAllBytes(tempPath)))
- using (var document = PdfiumViewer.PdfDocument.Load(ms))
- {
- for (int pageIndex = 0; pageIndex < document.PageCount; pageIndex++)
- {
- document.RotatePage(pageIndex, pdfRotation);
- // 可选:验证旋转结果
- // var currentRotation = document.Pages[pageIndex].Rotation;
- // Debug.Assert(currentRotation == (int)rotation);
- }
- // 执行修改操作(示例:旋转第一页)
- //document.RotatePage(1, PdfRotation.Rotate90);
- // 步骤3:保存到临时文件
- byte[] pdfBytes;
- using (var outputStream = new MemoryStream())
- {
- document.Save(outputStream);
- pdfBytes = outputStream.ToArray();
- }
- // 步骤4:强制释放文件锁定
- ForceReleasePdfFile(axControl, filePath);
- // 步骤5:原子替换文件
- File.WriteAllBytes(tempPath, pdfBytes);
- // File.Replace(tempPath, filePath, null, true);
- // 1. 复制替换文件到目标路径
- File.Copy(tempPath, filePath, overwrite: true);
- // 2. 删除临时文件(可选)
- File.Delete(tempPath);
- // 步骤6:验证加载
- axControl.LoadFile(filePath);
- return true;
- }
- }
- catch (IOException ex) when (ex.HResult == -2147024864)
- {
- if (attempt == MAX_RETRY - 1) throw;
- Thread.Sleep(RETRY_DELAY);
- }
- }
- return false;
- }
- public void ForceReleasePdfFile(AxAcroPDFLib.AxAcroPDF axControl, string filePath)
- {
- // 步骤1:深度释放COM对象
- ReleaseComObject(axControl);
- // 步骤2:内核级文件解锁
- UnlockFileHandle(filePath);
- // 步骤3:延迟重载验证
- Thread.Sleep(200);
- axControl.LoadFile(filePath);
- }
- private void ReleaseComObject(AxAcroPDFLib.AxAcroPDF axControl)
- {
- try
- {
- // 显式释放ActiveX资源
- if (axControl.IsDisposed) return;
- // 反射调用内部释放方法
- var type = axControl.GetType();
- var method = type.GetMethod("ReleaseOCX", BindingFlags.Instance | BindingFlags.NonPublic);
- method?.Invoke(axControl, null);
- // 强制垃圾回收
- GC.Collect();
- GC.WaitForPendingFinalizers();
- }
- catch (Exception ex)
- {
- }
- }
- // 修改后的P/Invoke声明
- [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- private static extern IntPtr CreateFile(
- string lpFileName,
- uint dwDesiredAccess,
- uint dwShareMode,
- IntPtr lpSecurityAttributes,
- FileMode dwCreationDisposition, // 改用.NET枚举
- FileAttributes dwFlagsAndAttributes, // 改用.NET枚举
- IntPtr hTemplateFile);
- // 修改后的UnlockFileHandle方法
- private void UnlockFileHandle(string filePath)
- {
- const uint FILE_SHARE_READ = 0x00000001;
- const uint FILE_SHARE_WRITE = 0x00000002;
- const uint GENERIC_READ = 0x80000000;
- IntPtr hFile = CreateFile(
- filePath,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- IntPtr.Zero,
- FileMode.Open, // 对应原生OPEN_EXISTING
- FileAttributes.Normal, // 对应原生FILE_ATTRIBUTE_NORMAL
- IntPtr.Zero);
- if (hFile != IntPtr.Zero && hFile != new IntPtr(-1))
- {
- CloseHandle(hFile);
- }
- }
- [DllImport("kernel32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool CloseHandle(IntPtr hObject);`
复制代码 调用代码:
[code] /// /// 当前旋转角度 /// public static int currentRotation = 0; /// /// 逆时针旋转 /// /// /// private void pictureEdit3_Click(object sender, EventArgs e) { if (axAcroPDF1.Visible) { currentRotation -= 90; PdfRotation pdfRotation = GetCounterClockwiseRotation(currentRotation); var path = axAcroPDF1.src; //调用旋转PDF保存方法 SafeSavePdfWithRelease(axAcroPDF1, path,pdfRotation); axAcroPDF1.LoadFile(path); axAcroPDF1.setView("Fit"); //适应窗口大小 } } /// /// 顺时针旋转 /// /// /// private void pictureEdit2_Click(object sender, EventArgs e) { if (axAcroPDF1.Visible) { currentRotation += 90; PdfRotation pdfRotation = GetCounterClockwiseRotation(currentRotation); var path = axAcroPDF1.src; //调用旋转PDF保存方法 SafeSavePdfWithRelease(axAcroPDF1, path, pdfRotation); axAcroPDF1.LoadFile(path); axAcroPDF1.setView("Fit"); //适应窗口大小 } } /// /// 通过旋转度数计算旋转的角度 /// /// 当前旋转角度 public static PdfRotation GetCounterClockwiseRotation(int counterClockwiseDegrees) { const int fullCircle = 360; int effectiveDegrees = counterClockwiseDegrees % fullCircle; if (effectiveDegrees < 0) effectiveDegrees += fullCircle; // 处理负角度 if (currentRotation >= 360) { currentRotation = 0; } if (currentRotation |