2014-06-26 86 views
0

我的應用程序是系統托盤應用程序,使用C#,.NET 4.0。許多線程,一種方法失敗

我試圖一次顯示許多PDF文件,每個PDF應該與其他窗口分割屏幕,我通過ProcessName確定,這就是全部。

難度在於我需要等到用戶關閉該窗口(.WaitForExit()方法),因爲稍後我將刪除PDF文件。這裏出現問題。

在第一個線程中一切正常,但問題是當我嘗試顯示第二個PDF文件窗口processList [0] THOUGH MoveWindow函數返回true,並且對該窗口的處理也是正確的只有pdf窗口正在調整大小,另一個窗口失敗。

在main方法我要創建的唯一線程(我稱之爲這段代碼幾次,每次用戶希望看到的PDF文件):

Thread pdfThread = new Thread(() => ShowPdfFile(fullPath)); 
pdfThread.Start(); 

然後(簡化代碼)

public static void ShowPdfFile(string fileName) 
     { 
      try 
      { 
       Process pdfProcess = Process.Start(fileName); 
       Thread.Sleep(500); 
       string windowTitle = GetActiveWindowTitle(); 
       IntPtr pdfHandle = (IntPtr)FindWindow(null, windowTitle); 
       MoveWindow(pdfHandle, 0, 0, 0, 0, true); 

       Process[] processList = Process.GetProcessesByName("someProcess"); 
       MoveWindow(processList[0].MainWindowHandle, 0, 0, 0, 0, true); 

       pdfProcess.WaitForExit(); 
       MoveWindow(processList[0].MainWindowHandle, 0, 0, max, max, true); 
      } 
      catch (Exception ex) 
      { 
       LogToFile(ex); 
      } 
      finally 
      { 
       try 
       { 
        File.Delete(fileName); 
       } 
       catch 
       { 
        LogToFile("Cannot delete file"); 
       } 
      } 

更新:嗯,我整天都在調試它,但現在我注意到在第二個線程它不等待在線pdfProcess.WaitForExit(); 我應該改變什麼來強制線程等待確切的pdfProcess退出?

+1

你能詳細說明這個問題嗎? –

+0

我認爲這基本上都是。你還想知道什麼? – DinosaurTom

+0

我無法動搖你的問題究竟是什麼? –

回答

1

丹尼爾是正確的,但我找到了解決方案!在這裏,也許有人會使用它。
小評論:我們必須使用winapi解決方案代替.WaitForExit()。
最重要的部分是while循環,等待關閉pdf窗口。
請記住,FindWindow()和IsWindow()方法來自user32.dll(winapi)。
此代碼基於它的路徑運行進程,然後獲取它的句柄並等待它關閉。

Process pdfProcess = new Process(); 
pdfProcess.StartInfo.FileName = filePath; 
if (pdfProcess.Start()) 
{ 
    Thread.Sleep(500); 
    Process[] processlist = Process.GetProcesses(); 
    string windowTitle = string.Empty; 

    foreach (Process process in processlist) 
    { 
     if (!String.IsNullOrEmpty(process.MainWindowTitle) && process.MainWindowTitle.Contains(fileName)) 
     { 
      windowTitle = process.MainWindowTitle; 
     } 
    } 
    IntPtr pdfHandle = FindWindow(null, windowTitle); 

    while (IsWindow(pdfHandle) && userExitedApp == false) 
     Thread.Sleep(100); 
} 
2

您的使用存在一個基本問題: 您爲每個文件啓動外部PDF應用程序。但是這並不能保證你有多個進程。

例如,Acrobat reader只啓動一個進程。其他文件將被「添加」爲第一個進程的新窗口(您可以通過嘗試手動打開Acrobat reader兩次來檢查此問題 - >將不起作用)。

簡而言之:如果您無法控制使用哪個PDF閱讀器(並且可以確保您對每個文件都有單個進程),則您的方法將無法工作。

注意:理論上可以等待用戶關閉包含特定文件的「閱讀器窗口」。但我強烈反對這項建議:

  1. 在不同的進程查找一個窗口很容易出錯(除非進程明確設計以這樣的方式......)
  2. 該解決方案將再次取決於閱讀器應用程序(你不能確保Acrobat和硝基採用類似的架構來僅舉兩個讀卡器)

原則上,如果這個功能是非常重要的,你應該考慮買一個PDF瀏覽器組件,它允許以顯示PDF文件作爲您自己流程的窗口。

編輯 的原因,第二個線程不等待的是一個文件「添加」到第一個進程的功能使用臨時過程:

  1. 臨時過程開始爲新的文件
  2. 臨時過程檢查,如果應用程序已經運行
  3. 臨時進程將通知第一個進程打開特定文件
  4. 臨時過程將會關閉。

因此,等待該進程將幾乎立即返回,因爲相關進程已經停止(或僅在幾毫秒內停止)。