欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#的Process類調(diào)用第三方插件實現(xiàn)PDF文件轉(zhuǎn)SWF文件

 更新時間:2016年11月24日 14:12:31   作者:彭澤0902  
本篇文章主要介紹了C#的Process類調(diào)用第三方插件實現(xiàn)PDF文件轉(zhuǎn)SWF文件,現(xiàn)在分享給大家,具有一定的參考價值,有需要的可以了解一下。

在項目開發(fā)過程中,有時會需要用到調(diào)用第三方程序?qū)崿F(xiàn)本系統(tǒng)的某一些功能,例如本文中需要使用到的swftools插件,那么如何在程序中使用這個插件,并且該插件是如何將PDF文件轉(zhuǎn)化為SWF文件的呢?接下來就會做一個簡單的介紹。

在.NET平臺中,對C#提供了一個操作對本地和遠程的訪問進程,使能夠啟動和停止系統(tǒng)進程。這個類就是System.Diagnostics.Process,我們首先來了解一下該類。

一.解析System.Diagnostics.Process類

在C#中使用Process類可以提供對本地和遠程的訪問進程,使能夠啟動和停止系統(tǒng)進程,并且該類可以對系統(tǒng)進程進行管理。該類中的一些常用方法:Start() ,Kill(),WaitForExit()等方法;StartInfo,F(xiàn)ileName,CreateNoWindow等屬性。

1.Start()方法:啟動(或重用)此 Process 組件的 StartInfo 屬性指定的進程資源,并將其與該組件關(guān)聯(lián)。如果啟動了進程資源,則為 true;如果沒有啟動新的進程資源(例如,如果重用了現(xiàn)有進程),則為 false。
具體介紹一下該方法的實現(xiàn)代碼:

 /// <devdoc>
    ///  <para> 
    ///  <see cref='System.Diagnostics.Process'/>如果過程資源被重用而不是啟動,重用的進程與此相關(guān)聯(lián)<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()方法:立即停止關(guān)聯(lián)的進程。Kill 強制終止進程,Kill 方法將異步執(zhí)行。 在調(diào)用 Kill 方法后,請調(diào)用 WaitForExit 方法等待進程退出,或者檢查 HasExited 屬性以確定進程是否已經(jīng)退出。
具體介紹一下該方法的實現(xiàn)代碼:

[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>
    /// 獲取進程的短期句柄,具有給定的訪問權(quán)限。
     ///如果句柄存儲在當(dāng)前進程對象中,則使用它。
     ///注意,我們存儲在當(dāng)前進程對象中的句柄將具有我們需要的所有訪問權(quán)限。
    /// </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'/>組件等待指定的毫秒數(shù),以使相關(guān)聯(lián)的進程退出。

具體介紹一下該方法的實現(xiàn)代碼:

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屬性:獲取或設(shè)置要傳遞給 Process 的 Start 方法的屬性。StartInfo 表示用于啟動進程的一組參數(shù)。 調(diào)用 Start 時,StartInfo 用于指定要啟動的進程。 唯一必須設(shè)置的 StartInfo 成員是 FileName 屬性。

具體介紹一下該方法的實現(xiàn)代碼:
 

 [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屬性:獲取或設(shè)置指示是否在新窗口中啟動該進程的值。

具體介紹一下該方法的實現(xiàn)代碼:

[
    DefaultValue(false),
    MonitoringDescription(SR.ProcessCreateNoWindow),
    NotifyParentProperty(true) 
    ]
    public bool CreateNoWindow { 
      get { return createNoWindow; } 
      set { createNoWindow = value; }
    }

 以上簡單介紹了該類的三種常用方法和兩種常用屬性,在實際的開發(fā)項目中無須對每個屬性方法和屬性的底層實現(xiàn)做全面的了解,但建議在學(xué)習(xí)該類的時候,適當(dāng)?shù)牧私庖幌履骋恍╊惖姆椒▽崿F(xiàn),有助于我們很好的掌握該類。

二.如何實現(xiàn)PDF文件轉(zhuǎn)化為SWF文件

在項目如果需要將PDF文件轉(zhuǎn)換為SWF文件,可以在項目中引入Swftools插件,該插件的主要功能:PDF到SWF轉(zhuǎn)換器。 每頁生成一幀。 使您能夠在Flash Movie中擁有完全格式化的文本,包括表格,公式,圖形等。 它基于Derek B. Noonburg的xpdf PDF解析器。

簡單介紹一下該插件的常用參數(shù):

-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的繪制順序,可能會導(dǎo)致結(jié)果與原來有差異

以上是幾種常用的參數(shù),具體擦參數(shù)列表詳見:http://www.swftools.org/。

對實現(xiàn)本次操作的類和插件做了一個簡單的介紹,接下來提供一個具體實現(xiàn)該功能的操作方法:
 

 /// <summary>
    /// PDF格式轉(zhuǎn)為SWF
    /// </summary>
    /// <param name="pdfPathParameter">原視頻文件地址,如/a/b/c.pdf</param>
    /// <param name="swfPathParameter">生成后的FLV文件地址,如/a/b/c.swf</param>
    /// <param name="beginpage">轉(zhuǎn)換開始頁</param>
    /// <param name="endpage">轉(zhuǎn)換結(jié)束頁</param>
    /// <param name="photoQuality">照片質(zhì)量</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("起始頁數(shù)大于結(jié)束頁數(shù)");
      }
      if (photoQuality <= 0)
      {
        throw new ArgumentException("照片質(zhì)量錯誤");
      }
      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中的圖片質(zhì)量
        sb.Append(" -j " + photoQuality);
        var command = sb.ToString();
        //Process提供對本地和遠程的訪問進程,使能夠啟動和停止系統(tǒng)進程。
        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)
        {
          //關(guān)閉進程
          p.Close();
          //釋放資源
          p.Dispose();
        }
      }

    }

三.小結(jié)

在本文中介紹了在C#中如何操作外部程序和線程的類System.Diagnostics.Process,并介紹了該類的一些常用方法的底層實現(xiàn)代碼,如果需要對該類進行詳細的了解,可以根據(jù)MSDN和.NET底層源碼的相關(guān)注釋和文章進行細致的學(xué)習(xí)。在介紹完實現(xiàn)操作的類的同時,也對Swftools插件做了一個說明,并列舉了相關(guān)的參數(shù),如果在項目中有較高的要求,可以根據(jù)官方提供的API文檔進行重構(gòu)。

在項目開發(fā)中,任何一個功能是無法做法完成所有的功能,在編碼功能時,只能盡可能的考慮到方法的通用性,在理解了某一個類和某一個插件的基本原理和使用方法后,可以根據(jù)對應(yīng)的API進行添加新功能。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論