我只是使用WebBrowser控件在WinForm中加载PDF文件。我有一个PDF字节数组,当用户点击我的应用程序中的打印预览时,我曾经在客户机的临时文件夹中写这个。
用户关闭表单后预览后,我需要删除该文件。在删除之前,我需要关闭为预览打开的Adobe Reader实例。
我尝试使用
获取进程列表Process[] processes = Process.GetProcessesByName("AcroRd32");
我可以通过这种方式终止进程并从临时文件夹中删除该文件。这是实际问题。假设用户已经为自己的目的打开了一个PDF文件,然后通过查找正在运行的实例并关闭它们,我也将关闭他的读者。
有没有办法找到我的应用程序打开的Adobe阅读器实例。我只需要检查Adobe阅读器。没有任何其他。
更新
我已经手动打开了adbobe reader,其中有文件名或MainWindowTitle作为Magazine.pdf。然后我在我的应用程序中通过webbrowser控件打开了adobe reader.But它的MainWindowTitle为Empty.Also应该有两个adobe reader但是在taskmanager它显示了四个实例,其中只有一个具有MainWindowTitle作为Magazine.pdf 请参阅以下图像以供参考
答案 0 :(得分:1)
检查每个Acrobat进程的MainWindowTitle - 您想要的那个将以临时文件的名称开头。
答案 1 :(得分:0)
您可以查看Process的MainWindowHandle属性。
答案 2 :(得分:0)
我不使用WebBrowser打开PDF,但是当我使用Process.MainWindowTitle()
时,我遇到了类似的问题。对于最后打开的Acrobat实例,它似乎只返回与“”不同的值。
我用来查找Acrobat的所有进程的C#代码如下:
Process[] myProcess = Process.GetProcessesByName("AcroRd32");
for (int i = 0; i < procesoProg.Length; i++)
{
if (myProcess[i].MainWindowTitle.Contains("MyTitle"))
{
myProcess[i].CloseMainWindow();
Thread.Sleep(300);
}
}
我尝试使用Process.Kill()
代替Process.MainWindow()
,但它会关闭所有Acrobat实例,而不仅仅是我想要的实例。
如果您只想关闭从应用程序打开的文档,则可以在启动PDF时存储该过程,并在要关闭它时使用CloseMainWindow()
:
private static Process myProcess = null;
public void OpenPDF()
{
myProcess = new Process();
myProcess.StartInfo.FileName = "AcroRd32.exe";
myProcess.StartInfo.Arguments = " /n /A \"pagemode=bookmarks&nameddest=" + strND + "\" \"" + strPath + "\"";
myProcess.Start();
}
public void ClosePDF()
{
// If there is
if (myProcess!= null)
{
myProcess.CloseMainWindow();
Thread.Sleep(500);
}
}
我希望这段代码可以帮到你。
答案 3 :(得分:0)
如果要删除在WebBrowser控件中打开的PDF文件,则必须使用以下代码:
WebBrowser.Navigate(YourPdfPath)
...
WebBrowser.Navigate("about:blank")
Application.DoEvents()
Dim millisecondsTimeout = 5000
While True
Try
File.Delete(YourPdfPath)
Exit While
Catch ex As IOException
If millisecondsTimeout < 0 Then Exit Sub
millisecondsTimeout -= 100
Thread.Sleep(100)
End Try
End While
更新:
我找到了一种杀死进程子进程的扩展方法:
<Extension>
Public Sub KillChildren(process As Process, Optional processNameToKill As String = "", Optional recursive As Boolean = False)
Static ProcessIDStack As List(Of Integer) = New List(Of Integer)
If ProcessIDStack.Contains(process.Id) Then
Exit Sub
Else
ProcessIDStack.Add(process.Id)
End If
Dim searcher = New ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" & process.Id) 'MLHIDE
Dim moc As ManagementObjectCollection = searcher.Get
For Each mo As ManagementObject In moc
Try
Dim ChildProcess = process.GetProcessById(Convert.ToInt32(mo("ProcessID"))) 'MLHIDE
If recursive Then
ChildProcess.KillChildren(processNameToKill, recursive)
End If
If (Not ChildProcess.HasExited) AndAlso (processNameToKill = String.Empty OrElse ChildProcess.ProcessName = processNameToKill) Then
ChildProcess.Kill()
ChildProcess.WaitForExit(1000)
End If
Catch ex As ArgumentException
' process already exited
Catch ex As InvalidOperationException
' process already exited
Catch ex As ComponentModel.Win32Exception
' process already exited
End Try
Next
ProcessIDStack.Remove(process.Id)
End Sub
...
WebBrowser.Navigate("about:blank")
Process.GetCurrentProcess.KillChildren("AcroRd32", True)
Application.DoEvents()
...
我正在寻找一种更好的方法来检查文件是否未被使用,避免在循环内睡觉(Andrew Barber正确地说这不是一个好的代码......)但我没有找到任何其他内容,遗憾...
(感谢Andrew Barber)