在项目开发过程中,有时会需要用到调用第三方程序实现本系统的某一些功能,例如本文中需要使用到的swftools插件,那么如何在程序中使用这个插件,并且该插件是如何将PDF文件转化为SWF文件的呢?接下来就会做一个简单的介绍。
在.NET平台中,对C#提供了一个操作对本地和远程的访问进程,使能够启动和停止系统进程。这个类就是System.Diagnostics.Process,我们首先来了解一下该类。
一.解析System.Diagnostics.Process类
在C#中使用Process类可以提供对本地和远程的访问进程,使能够启动和停止系统进程,并且该类可以对系统进程进行管理。该类中的一些常用方法:Start() ,Kill(), WaitForExit()等方法;StartInfo,FileName,CreateNoWindow等属性。
1.Start()方法:启动(或重用)此 Process 组件的 StartInfo 属性指定的进程资源,并将其与该组件关联。如果启动了进程资源,则为 true;如果没有启动新的进程资源(例如,如果重用了现有进程),则为 false。
具体介绍一下该方法的实现代码:
/// <devdoc> /// <para> /// <see cref='System.Diagnostics.Process'/>如果过程资源被重用而不是启动,重用的进程与此相关联<see cref ='System.Diagnostics.Process'/>零件。 /// </para> /// </devdoc> [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] public bool Start() { Close(); ProcessStartInfo startInfo = StartInfo; if (startInfo.FileName.Length == 0) throw new InvalidOperationException(SR.GetString(SR.FileNameMissing)); if (startInfo.UseShellExecute) { #if !FEATURE_PAL return StartWithShellExecuteEx(startInfo); #else throw new InvalidOperationException(SR.GetString(SR.net_perm_invalid_val, "StartInfo.UseShellExecute", true)); #endif // !FEATURE_PAL } else { return StartWithCreateProcess(startInfo); } }
2.Kill()方法:立即停止关联的进程。Kill 强制终止进程,Kill 方法将异步执行。 在调用 Kill 方法后,请调用 WaitForExit 方法等待进程退出,或者检查 HasExited 属性以确定进程是否已经退出。
具体介绍一下该方法的实现代码:
[ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void Kill() { SafeProcessHandle handle = null; try { handle = GetProcessHandle(NativeMethods.PROCESS_TERMINATE); if (!NativeMethods.TerminateProcess(handle, -1)) throw new Win32Exception(); } finally { ReleaseProcessHandle(handle); } }
SafeProcessHandle GetProcessHandle(int access) { return GetProcessHandle(access, true); } /// <devdoc> /// 获取进程的短期句柄,具有给定的访问权限。 ///如果句柄存储在当前进程对象中,则使用它。 ///注意,我们存储在当前进程对象中的句柄将具有我们需要的所有访问权限。 /// </devdoc> /// <internalonly/> [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] SafeProcessHandle GetProcessHandle(int access, bool throwIfExited) { Debug.WriteLineIf(processTracing.TraceVerbose, "GetProcessHandle(access = 0x" + access.ToString("X8", CultureInfo.InvariantCulture) + ", throwIfExited = " + throwIfExited + ")"); #if DEBUG if (processTracing.TraceVerbose) { StackFrame calledFrom = new StackTrace(true).GetFrame(0); Debug.WriteLine(" called from " + calledFrom.GetFileName() + ", line " + calledFrom.GetFileLineNumber()); } #endif if (haveProcessHandle) { if (throwIfExited) { //因为hasProcessHandle是true,我们知道我们有进程句柄 //打开时至少要有SYNCHRONIZE访问,所以我们可以等待它 // zero timeout以查看进程是否已退出。 ProcessWaitHandle waitHandle = null; try { waitHandle = new ProcessWaitHandle(m_processHandle); if (waitHandle.WaitOne(0, false)) { if (haveProcessId) throw new InvalidOperationException(SR.GetString(SR.ProcessHasExited, processId.ToString(CultureInfo.CurrentCulture))); else throw new InvalidOperationException(SR.GetString(SR.ProcessHasExitedNoId)); } } finally { if( waitHandle != null) { waitHandle.Close(); } } } return m_processHandle; } else { EnsureState(State.HaveId | State.IsLocal); SafeProcessHandle handle = SafeProcessHandle.InvalidHandle; #if !FEATURE_PAL handle = ProcessManager.OpenProcess(processId, access, throwIfExited); #else IntPtr pseudohandle = NativeMethods.GetCurrentProcess(); // Get a real handle if (!NativeMethods.DuplicateHandle (new HandleRef(this, pseudohandle), new HandleRef(this, pseudohandle), new HandleRef(this, pseudohandle), out handle, 0, false, NativeMethods.DUPLICATE_SAME_ACCESS | NativeMethods.DUPLICATE_CLOSE_SOURCE)) { throw new Win32Exception(); } #endif // !FEATURE_PAL if (throwIfExited && (access & NativeMethods.PROCESS_QUERY_INFORMATION) != 0) { if (NativeMethods.GetExitCodeProcess(handle, out exitCode) && exitCode != NativeMethods.STILL_ACTIVE) { throw new InvalidOperationException(SR.GetString(SR.ProcessHasExited, processId.ToString(CultureInfo.CurrentCulture))); } } return handle; } }
3.WaitForExit()方法:指示<see cref ='System.Diagnostics.Process'/>组件等待指定的毫秒数,以使相关联的进程退出。
具体介绍一下该方法的实现代码:
public bool WaitForExit(int milliseconds) { SafeProcessHandle handle = null; bool exited; ProcessWaitHandle processWaitHandle = null; try { handle = GetProcessHandle(NativeMethods.SYNCHRONIZE, false); if (handle.IsInvalid) { exited = true; } else { processWaitHandle = new ProcessWaitHandle(handle); if( processWaitHandle.WaitOne(milliseconds, false)) { exited = true; signaled = true; } else { exited = false; signaled = false; } } } finally { if( processWaitHandle != null) { processWaitHandle.Close(); } // If we have a hard timeout, we cannot wait for the streams if( output != null && milliseconds == -1) { output.WaitUtilEOF(); } if( error != null && milliseconds == -1) { error.WaitUtilEOF(); } ReleaseProcessHandle(handle); } if (exited && watchForExit) { RaiseOnExited(); } return exited; }
internal ProcessWaitHandle( SafeProcessHandle processHandle): base() { SafeWaitHandle waitHandle = null; bool succeeded = NativeMethods.DuplicateHandle( new HandleRef(this, NativeMethods.GetCurrentProcess()), processHandle, new HandleRef(this, NativeMethods.GetCurrentProcess()), out waitHandle, 0, false, NativeMethods.DUPLICATE_SAME_ACCESS); if (!succeeded) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } this.SafeWaitHandle = waitHandle; }
4.StartInfo属性:获取或设置要传递给 Process 的 Start 方法的属性。StartInfo 表示用于启动进程的一组参数。 调用 Start 时,StartInfo 用于指定要启动的进程。 唯一必须设置的 StartInfo 成员是 FileName 属性。
具体介绍一下该方法的实现代码:
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), MonitoringDescription(SR.ProcessStartInfo)] public ProcessStartInfo StartInfo { get { if (startInfo == null) { startInfo = new ProcessStartInfo(this); } return startInfo; } [ResourceExposure(ResourceScope.Machine)] set { if (value == null) { throw new ArgumentNullException("value"); } startInfo = value; } }
5.CreateNoWindow属性:获取或设置指示是否在新窗口中启动该进程的值。
具体介绍一下该方法的实现代码:
[ DefaultValue(false), MonitoringDescription(SR.ProcessCreateNoWindow), NotifyParentProperty(true) ] public bool CreateNoWindow { get { return createNoWindow; } set { createNoWindow = value; } }
以上简单介绍了该类的三种常用方法和两种常用属性,在实际的开发项目中无须对每个属性方法和属性的底层实现做全面的了解,但建议在学习该类的时候,适当的了解一下某一些类的方法实现,有助于我们很好的掌握该类。
二.如何实现PDF文件转化为SWF文件
在项目如果需要将PDF文件转换为SWF文件,可以在项目中引入Swftools插件,该插件的主要功能:PDF到SWF转换器。 每页生成一帧。 使您能够在Flash Movie中拥有完全格式化的文本,包括表格,公式,图形等。 它基于Derek B. Noonburg的xpdf PDF解析器。
简单介绍一下该插件的常用参数:
-h , –help Print short help message and exit 打印帮助信息
-V , –version Print version info and exit 打印版本号
-o , –output file.swf Direct output to file.swf. If file.swf contains ‘13568621′ (file13568630.swf), then each page指定输出的swf文件名
-P , –password password Use password for deciphering the pdf.指定打开pdf的密码
-z , –zlib Use Flash 6 (MX) zlib compression.使用Flash 6的zlib压缩机制
-i , –ignore Allows pdf2swf to change the draw order of the pdf. This may make the generated允许程序修改pdf的绘制顺序,可能会导致结果与原来有差异
以上是几种常用的参数,具体擦参数列表详见:http://www.swftools.org/。
对实现本次操作的类和插件做了一个简单的介绍,接下来提供一个具体实现该功能的操作方法:
/// <summary> /// PDF格式转为SWF /// </summary> /// <param name="pdfPathParameter">原视频文件地址,如/a/b/c.pdf</param> /// <param name="swfPathParameter">生成后的FLV文件地址,如/a/b/c.swf</param> /// <param name="beginpage">转换开始页</param> /// <param name="endpage">转换结束页</param> /// <param name="photoQuality">照片质量</param> /// <returns></returns> public static bool PdfConversionSwf(string pdfPathParameter, string swfPathParameter, int beginpage, int endpage, int photoQuality) { if (string.IsNullOrEmpty(pdfPathParameter)) { throw new ArgumentNullException(pdfPathParameter); } if (string.IsNullOrEmpty(swfPathParameter)) { throw new ArgumentNullException(swfPathParameter); } if (endpage < beginpage) { throw new ArgumentException("起始页数大于结束页数"); } if (photoQuality <= 0) { throw new ArgumentException("照片质量错误"); } var exe = HttpContext.Current.Server.MapPath("~/tools/swftools-2013-04-09-1007.exe"); var pdfPath = HttpContext.Current.Server.MapPath(pdfPathParameter); var swfPath = HttpContext.Current.Server.MapPath(swfPathParameter); Process p = null; try { if (!File.Exists(exe) || !File.Exists(pdfPath)) { return false; } if (File.Exists(swfPath)) { File.Delete(swfPath); } var sb = new StringBuilder(); sb.Append(" \"" + pdfPath + "\""); sb.Append(" -o \"" + swfPath + "\""); sb.Append(" -s flashversion=9"); sb.Append(" -s disablelinks"); if (endpage > GetPageCount(pdfPath)) { endpage = GetPageCount(pdfPath); } sb.Append(" -p " + "\"" + beginpage + "" + "-" + endpage + "\""); //SWF中的图片质量 sb.Append(" -j " + photoQuality); var command = sb.ToString(); //Process提供对本地和远程的访问进程,使能够启动和停止系统进程。 p = new Process { StartInfo = { FileName = exe, Arguments = command, WorkingDirectory = HttpContext.Current.Server.MapPath("~/Bin/"), UseShellExecute = false, RedirectStandardError = true, CreateNoWindow = false } }; //启动线程 p.Start(); //开始异步读取 p.BeginErrorReadLine(); //等待完成 p.WaitForExit(); //开始同步读取 //p.StandardError.ReadToEnd(); if (!File.Exists(swfPath)) return false; return true; } catch (IOException ioex) { throw new IOException(ioex.Message); } catch (Exception ex) { throw new Exception(ex.Message); } finally { if (p != null) { //关闭进程 p.Close(); //释放资源 p.Dispose(); } } }
三.小结
在本文中介绍了在C#中如何操作外部程序和线程的类System.Diagnostics.Process,并介绍了该类的一些常用方法的底层实现代码,如果需要对该类进行详细的了解,可以根据MSDN和.NET底层源码的相关注释和文章进行细致的学习。在介绍完实现操作的类的同时,也对Swftools插件做了一个说明,并列举了相关的参数,如果在项目中有较高的要求,可以根据官方提供的API文档进行重构。
在项目开发中,任何一个功能是无法做法完成所有的功能,在编码功能时,只能尽可能的考虑到方法的通用性,在理解了某一个类和某一个插件的基本原理和使用方法后,可以根据对应的API进行添加新功能。
备注:由于博客搬家出现问题,有关本人的其他.NET文章,请访问:
http://www.cnblogs.com/pengze0902/
相关推荐
然而,直接将Office和PDF转换为SWF的功能并不内置在.NET Framework中,所以我们需要借助第三方库或者服务来完成这个任务。 对于将Office文件转换为PDF,可以使用Aspose.Cells、Aspose.Words或Apache POI等库。这些...
在C# WinForm开发中,有时我们需要集成或调用系统中已经安装的第三方应用程序,以扩展我们应用程序的功能或提供更多的用户交互。这个实例将详细讲解如何在C# WinForm应用中实现这一目标。 首先,我们需要了解`...
本话题聚焦于使用C/C++编程语言调用Adobe Acrobat Reader DC来实现PDF文件的打印功能。Adobe Acrobat Reader DC是一款广泛使用的PDF阅读器,它提供了丰富的API接口,允许开发者通过编程方式控制其行为,包括打开、...
采用C#开发语言,借助第三方Aspose.Pdf.dll及Spire.Pdf.dll 对pdf文件进行处理,可以把pdf文件转换成doc 或者docx png等格式,通过代码大家可以进行自己重新开发,核心代码已经编写完成,下载后可以直接运行进行pdf...
对于处理PDF文档,C#提供了多种方法来实现PDF文件的打印功能,允许开发者指定特定的打印机进行输出。本文将详细介绍如何在C#环境下实现PDF文件的打印功能。 首先,理解PDF(Portable Document Format)是一种通用的...
下面将详细介绍如何在UE4插件中调用第三方库。 1. **创建插件** 首先,你需要创建一个UE4插件。在项目的`Plugins`目录下,运行`GenerateProjectFiles.bat`来更新项目文件,然后创建一个新的子目录,命名为你的插件...
在C#中将PDF文件转换为Word文档,可以借助如Aspose这样的第三方库实现。通过理解这些库的工作原理和提供的API,你可以轻松地集成到自己的项目中,实现文件格式的转换。在实际操作中,需要注意保持格式一致性和处理...
总结起来,C#实现异步调用外部程序的关键在于理解和运用`async/await`、`Process`类以及异步等待的策略。通过这种方式,我们可以在不阻塞主线程的情况下执行外部程序,并获取其输出,从而提高应用程序的性能和用户...
本文将详细讲解使用C#语言借助第三方DLL库实现PDF转图片的流程和关键技术点。 首先,从标题"**C# pdf 转图片第三方dll**"我们可以知道,我们将使用C#编程语言,利用第三方DLL库来完成这项任务。C#是.NET框架的一...
- 第三方在线服务:如果不想自行开发,可以考虑使用PDF转Word的在线API,如Google Drive或Microsoft OneDrive的转换功能。 以上是关于在C#中将PDF文件转换为Word文件的基本知识,实际应用中需要根据具体需求进行...
本教程将详细介绍如何使用C#编程语言,借助SWFTools工具将PDF文件转换为SWF格式。 首先,我们需要了解SWFTools。SWFTools是一套开源工具集,由Adobe公司维护,用于处理与Flash相关的任务,其中包括将PDF转换为SWF的...
本篇文章将深入探讨如何使用C#调用打印机来打印PDF文件,特别是借助第三方库O2S.Components.PDFRender4NET.dll。这个库提供了一个高效且便捷的方式来处理PDF文档的打印任务。 首先,我们需要理解C#中的打印机制。在...
首先,你需要引入一个第三方库,因为.NET Framework的标准库并不直接支持PDF到Word的转换。一个常用的库是iTextSharp,它是一个强大的PDF处理库,虽然主要用于读写PDF,但可以通过一些技巧转换为其他格式。另一个是...
C#调用process执行DOS命令,间接调用其他软件或进程
C# ,asp.net 实现Pdf文件转html功能 读取硬盘路径下的Pdf文件,转化为html保存到硬盘,上网下载Aspose.Pdf.dll
本项目是利用C#来实现一个功能,即把DWG(AutoCAD图形设计软件的默认格式)文件转换为PDF文档。这种转换在工程、建筑、设计等领域中非常常见,因为它允许用户方便地分享和打印CAD图纸,而无需拥有原始的CAD软件。 ...
在C#中调用bat文件,主要利用`System.Diagnostics.Process`类。以下是一步一步的实现步骤: 1. 引入命名空间:在C#代码中,首先需要引入`System.Diagnostics`命名空间,因为它包含`Process`类。 ```csharp using ...