2014-06-26 51 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. 临时过程将会关闭。

因此,等待该进程将几乎立即返回,因为相关进程已经停止(或仅在几毫秒内停止)。