往期回顧
.Net初次使用FlashPaper主要講述了.Net使用FlashPaper來進行文檔轉換,同時也留下了一些問題等待我們解決:
- 不能同時轉換多個文件,否則將導致失敗
- 如果轉換失敗導致進程不結束,將會照成死循環
- Office文件總轉換失敗,之前能成功
不能同時轉換多個文件,否則將導致失敗
因為我的需求是小數量人員使用系統,所以用了加鎖的形式來保證同一時刻只有一個轉換進程。
//創建一個靜態類,靜態變量,供鎖使用 public class PageHelper : System.Web.UI.Page { public static Object LockObject = 0; } //調用轉換代碼 protected void btnConvertFile_Click(object sender, EventArgs e) { if (Monitor.TryEnter(LockObject)) { //轉換操作 if(ConvertFile("Test.doc")) ShowMessage("轉換成功!"); else ShowMessage("轉換失敗!"); Monitor.Exit(PageHelper.LockObject); } else { //告知請稍等 ShowMessage("有操作正在進行,請稍后再試!") } }
如果轉換失敗導致進程不結束,將會照成死循環
當轉換進程不結束時 pss.HasExited 一直為false。所以代碼更改如下。
protected Boolean ConvertFile(string fileName) { //FlashPaper文件安裝路徑 可自行設置 string flashPrinter = Server.MapPath("~/FlashPaper/FlashPrinter.exe"); string inFile = GetFilePath(fileName); string outFile = GetFlashPath(GetFlashName(fileName)); //進程操作 Process pss = new Process(); pss.StartInfo.CreateNoWindow = false; pss.StartInfo.FileName = flashPrinter; pss.StartInfo.Arguments = string.Format("{0} {1} -o {2}", flashPrinter, inFile, outFile); try { pss.Start(); //設置300*200毫秒不結束則退出循環 for (int i = 0; i < 300 && !File.Exists(outFile); i += 1) System.Threading.Thread.Sleep(200); //返回輸出文件是否存在 return File.Exists(outFile); } catch (Exception) { //如果報錯 將輸出文件刪除 if (File.Exists(outFile)) File.Delete(outFile); return false; } }
Office文件總轉換失敗,之前能成功
發布后使用時發現Office總是轉換失敗,本地測試完全正常。調查中發現服務器任務管理器中有很多FlashPaper進程和Office各各組件的進程,結合FlashPaper轉換原理。得出結論:Office組件被FlashPaper打開后,未正常關閉,導致進程長期駐留在任務管理器中,導致后續轉換無法進行。
心想難道在服務器端,進程無法自動關閉。於是在代碼中增加了殺死進程樹的功能
protected Boolean ConvertFile(string fileName) { //FlashPaper文件安裝路徑 可自行設置 string flashPrinter = Server.MapPath("~/FlashPaper/FlashPrinter.exe"); string inFile = GetFilePath(fileName); string outFile = GetFlashPath(GetFlashName(fileName)); //進程操作 Process pss = new Process(); pss.StartInfo.CreateNoWindow = false; pss.StartInfo.FileName = flashPrinter; pss.StartInfo.Arguments = string.Format("{0} {1} -o {2}", flashPrinter, inFile, outFile); try { pss.Start(); //設置300*200毫秒不結束則退出循環 for (int i = 0; i < 300 && !File.Exists(outFile); i += 1) System.Threading.Thread.Sleep(200); //返回輸出文件是否存在 return File.Exists(outFile); } catch (Exception) { //如果報錯 將輸出文件刪除 if (File.Exists(outFile)) File.Delete(outFile); return false; } finally { //如果進程還未結束,殺死進程樹 if (!pss.HasExited) KillProcess(pss.Id); } } //殺死進程樹 private static bool KillProcess(int pid) { Process[] procs = Process.GetProcesses(); for (int i = 0; i < procs.Length; i++) { if (GetParentProcess(procs[i].Id) == pid) KillProcess(procs[i].Id); } try { Process myProc = Process.GetProcessById(pid); myProc.Kill(); } catch (ArgumentException) { ; } return true; } //獲取父進程 private static int GetParentProcess(int Id) { int parentPid = 0; using (ManagementObject mo = new ManagementObject("win32_process.handle='" + Id.ToString(CultureInfo.InvariantCulture) + "'")) { try { mo.Get(); } catch (ManagementException) { return -1; } parentPid = Convert.ToInt32(mo["ParentProcessId"], CultureInfo.InvariantCulture); } return parentPid; }
發布后,跟蹤發現,轉換完成后FlashPaper真的沒有了,但是Office進程卻依然存在,好郁悶啊。隨后在網絡收集各種方法,都未能達到想要的效果。這可是真真的郁悶啊。
最后無奈在服務器上閑逛,想看看是不是設置的問題。在服務器端打開Office組件查看,誰知竟彈出窗口:
難道是因為這個對話框導致Office未正常關閉。和很多葯品廣告一樣:“我抱着試試看的態度”用Office Toolkit把Office2010激活。
手動殺死所有已開阻攔進程,啟動系統,轉換開始。
啊~成功。沒想到真是這個激活窗口導致了這個問題。希望大家引以為戒,以免浪費了青春。
Demo下載
最后提供Demo下載:在線Flash轉換.rar