.NET (C#) 进程和Adobe Acrobat
好的,事情是这样的...
我有一个 .NET 2.0 (C#) 中的 Windows (XP) 程序,它允许用户重命名给定的 .pdf 文件。 (文件名是“结构描述性的”,因为它列出了有关文件本身内容的简单信息。)在程序的唯一形式上,有一个 LinkLabel 对象,允许用户打开 .pdf 本身,以便他们可以看到他们正在重命名什么。
诀窍在于,当用户进行适当的更改并单击“保存”按钮时,我希望显示 .pdf 的 Acrobat 窗口关闭、执行保存、检索“下一个”文件以及立即打开显示下一个文件的新窗口。
以下是相关的代码片段:
private void OpenViewer()
{
// NOTE: pdfView is of type Process, in case you're not familiar with
// Process.Start().
pdfView = System.Diagnostics.Process.Start(lnkFile.Links[0].LinkData.ToString());
}
private bool KillViewer()
{
bool result = (pdfView != null);
if (pdfView != null)
{
pdfView.CloseMainWindow();
pdfView.Close();
pdfView.Dispose();
pdfView = null;
GC.Collect();
// Verify that the lock is available before you return, as returning basically says:
// "Yup, the file's available."
bool locked = false;
StreamWriter sw = null;
do
{
try
{
sw = new StreamWriter(new FileStream(lnkFile.Links[0].LinkData.ToString(), FileMode.Open));
locked = false;
}
catch (Exception)
{
locked = true;
}
} while (locked);
sw.Dispose();
}
return result;
}
private void SomeButtonEvent
{
// Record whether a viewer was open in the first place.
bool viewerActive = KillViewer();
PerformFileLockingMethod();
GetNextFile()
if(viewerActive)
{
OpenViewer();
}
}
请注意,KillViewer() 中基本上有一个锁抓取循环,以确保程序在 pdf 查看器完全释放锁之前不会尝试重命名工作文件。
问题是这样的:有时这一切都工作得很好,有时 KillViewer 在 CloseMainWindow() 调用上崩溃,并出现 InvalidOperationException,详细信息 =“进程已退出,因此请求的信息不可用。”。如果不是因为两件事,这将是相当简单的...
1: pdfView.HasExited = true
AND
2: 该死的 pdf 查看器仍然打开!!!
这到底是怎么可能的?我应该使用一个进程命令来确保窗口关闭吗?仅供参考,该程序不会引用 System.* 命名空间之外的任何内容,或者最终也仅引用 System.* 的内部构建类。
谢谢。
Okay, here's the deal...
I have a Windows (XP) program in .NET 2.0 (C#) which allows users to rename a given .pdf file. (The filename is "structurally descriptive", as it lays out simple info about what's in the file itself.) On the program's only form, there is a LinkLabel object which allows the user to open the .pdf itself, so that they can see what they are renaming.
The trick is that, when the user makes the appropriate change(s) and clicks the "Save" button, I want the Acrobat window showing the .pdf to close, the save performed, a "next" file to be retrieved, and a new window to immediately open displaying that next file.
Here's the relevant code snippets:
private void OpenViewer()
{
// NOTE: pdfView is of type Process, in case you're not familiar with
// Process.Start().
pdfView = System.Diagnostics.Process.Start(lnkFile.Links[0].LinkData.ToString());
}
private bool KillViewer()
{
bool result = (pdfView != null);
if (pdfView != null)
{
pdfView.CloseMainWindow();
pdfView.Close();
pdfView.Dispose();
pdfView = null;
GC.Collect();
// Verify that the lock is available before you return, as returning basically says:
// "Yup, the file's available."
bool locked = false;
StreamWriter sw = null;
do
{
try
{
sw = new StreamWriter(new FileStream(lnkFile.Links[0].LinkData.ToString(), FileMode.Open));
locked = false;
}
catch (Exception)
{
locked = true;
}
} while (locked);
sw.Dispose();
}
return result;
}
private void SomeButtonEvent
{
// Record whether a viewer was open in the first place.
bool viewerActive = KillViewer();
PerformFileLockingMethod();
GetNextFile()
if(viewerActive)
{
OpenViewer();
}
}
Notice in KillViewer() that there's basically a lock-grabbing loop to make sure that the program doesn't try to rename the working file until after the pdf viewer has fully released the lock.
The problem is this: sometimes this all works beautifully, and sometimes KillViewer breaks down on the CloseMainWindow() call, with an InvalidOperationException, details = "Process has exited, so the requested information is not available.". This would be fairly straightforward if it weren't for two things...
1: pdfView.HasExited = true
AND
2: The darned pdf viewer is STILL OPEN!!!
How in the world is this possible? Is there a process command I should be using to ensure the window closes? FYI, the program references nothing outside of either System.* namespaces, or internally built class which also ultimately reference only System.*.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
试试这个吧..
Try this instead..
经过进一步调查,我想我已经确定发生了什么事。
我没有详细说明工作流程细节,因为我无法可靠地复制这种情况。经过进一步的尝试,我发现了两种可靠的情况...
在每种情况下,问题都归结为 pdfViewer 指向的进程与用户正在执行的操作不同步。
如果多次单击该链接,则活动查看器所在的进程与 pdfViewer 的进程没有连接,因此出现上面详述的看似不可能的情况。
如果单击链接并关闭窗口,则 pdfViewer 变量将保留,留下 HasExited = true 的进程。
如果单击链接并关闭窗口,则 pdfViewer 变量
所有这一切的教训如下:如果您正在从主用户界面运行单独的进程,请绝对确保您涵盖了外部进程可能发生的所有可能情况。
郑重声明,Nick Guerrera 为我指引了进程 ID,值得加分。最终解决了这个问题。
After further investigation, I think I've determined what was going on.
I didn't detail workflow details because I couldn't reliably replicate the situation. After further attempts, I found two reliable situations...
In each of these cases, the problem boiled down to the Process pointed to by pdfViewer becoming out of sync with what the user was doing.
If the link was clicked on multiple times, then the active viewer was on a process not connected with pdfViewer's process, hence the seemingly impossible situation detailed above.
If the link was clicked on and the window closed, the pdfViewer variable would remain, leaving a process with HasExited = true.
The take home lesson of all this is as follows: If you're running a separate process from your main user interface, make ABSOLUTELY SURE that you cover every possible situation that could occur with the external process.
For the record, Nick Guerrera deserves points for directing me towards the process IDs. That ultimately solved it.