文档章节

C#的Process类调用第三方插件实现PDF文件转SWF文件

彭泽0902
 彭泽0902
发布于 2016/11/24 18:47
字数 2024
阅读 5
收藏 0
点赞 0
评论 0

     在项目开发过程中,有时会需要用到调用第三方程序实现本系统的某一些功能,例如本文中需要使用到的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进行添加新功能。

 

 

© 著作权归作者所有

共有 人打赏支持
彭泽0902
粉丝 0
博文 44
码字总数 57771
作品 0
武汉
高级程序员
FlexPaper+SwfTools实现的在线文档功能

最近一个项目需要实现一个在线浏览文档的功能。准备使用FlexPaper配合Pdf2Swf实现。 主要需求在于: ➔ 文档页数很多,少则几百页,多则上千页。 ➔ 相应的文档大小也在50MB以上。 根据需求,...

长平狐 ⋅ 2012/11/06 ⋅ 4

FlexPaper实现文档在线浏览(附源码)

园子里也有关于FlexPaper的文章,但都不怎么详细。 没有较全的参数说明。就连官方网站都没有。没法,最后只得将swf文件反编译后查看了源码才将里面的参数全部弄出来。 好了,废话不多说,开始...

云栖希望。 ⋅ 2017/12/10 ⋅ 0

Centos下安装类百度文库环境

使用php实现百度文库功能,网上搜索到的方案,实现doc转pdf,pdf转swf,然后显示出来。 这里简单的记录下,【doc转pdf,pdf转swf】两个功能的搭建流程。 doc转pdf 使用到下列程序(文件): Ap...

DragonFK ⋅ 2013/02/20 ⋅ 1

FlexPager Developer Guide(FlexPager使用指南)

资料列表: 源码下载:http://code.google.com/p/flexpaper/ 官方文档:http://flexpaper.devaldi.com/docs.htm SWF工具下载:http://www.swftools.org/download.html 1、将PDF图片等转换成S......

晨曦之光 ⋅ 2012/03/09 ⋅ 0

实现仿百度文库在线浏览功能

针对office文档的在线浏览功能,解决方案有以下几种,其中各有优劣之处。此次只对解决思路做个说明,具体实现会在后面的博文中做说明。 方案一:使用微软的dsoframer.ocx,该插件不在此详细介...

Bingo许 ⋅ 2014/01/02 ⋅ 4

flexpaper openOffice+pdf2swf类百度文库):pdf转swf(Linu...

1:工具准备 swftools.exe 下载 http://www.swftools.org/download.html 安装至D盘 SWFTools提供了一系列将各种文件转成swf的工具: font2swf.exe gif2swf.exe jpeg2swf.exe pdf2swf.exe pn......

功夫panda ⋅ 2013/02/02 ⋅ 0

java实现附件预览(openoffice+swftools+flexpaper)

先附上本人参考的文章,基于的 flexpaper版本 为 1.5,本人由于使用的是 2.1.9 ,故之后说明: 已经支持加载中文文件名 代码下载 1.概述 主要原理 1.通过第三方工具openoffice,将word、exc...

DavidBao ⋅ 2015/09/16 ⋅ 1

如何使用asp.net调用具有管理员权限的cmd,急,在线等

ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = "cmd.exe"; startInfo.Arguments = "/c C:\Windows\System32\cmd.exe"; startInfo.RedirectStandardInput = tr......

2251620140 ⋅ 2014/05/18 ⋅ 1

openoffice启动服务

安装PDF转换和文档在线预览插件后,管理员可以设置只允许用户下载文档的PDF版本,而无法下载原始文档;或者管理员可以设置用户只能通过浏览器在线预览文档内容,无法下载文档,或者复制/粘贴...

DavidBao ⋅ 2015/09/24 ⋅ 0

C#实现判断文件是否被占用与解除文件占用

最近遇到一个问题,我在实现一个C#客户端的附件上传功能时,只能上传未被其他进程占用的文件,因此每次上传文件前需要先判断被选中文件是否被占用。尤其是PDF文件,当以AdobeReaderXI打开时,...

北风其凉 ⋅ 2016/11/03 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 44分钟前 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

eclipse酷炫大法之设置主题、皮肤

eclipse酷炫大法 目前两款不错的eclipse 1.系统设置 Window->Preferences->General->Appearance 2.Eclipse Marketplace下载【推荐】 Help->Eclipse Marketplace->搜索‘theme’进行安装 比如......

anlve ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部