【问题标题】:C# Process.Start, how to prevent re-use of existing application?C# Process.Start,如何防止重复使用现有应用程序?
【发布时间】:2023-03-30 12:27:01
【问题描述】:

我在一个程序中编写一个功能,用户可以编辑存储在数据库中的文档,它将文档保存到一个临时文件夹,然后使用 Process.Start 将文档启动到编辑应用程序中,例如 Microsoft Word。

然后我的应用程序需要等到他们关闭被调用的进程并将数据库中的文档替换为临时文件夹中新编辑的副本。

只要被调用的应用程序尚未运行,以下代码就可以正常工作:

ProcessStartInfo pInfo = new ProcessStartInfo();
pInfo.FileName=TempFolder + Path.DirectorySeparatorChar + f.Name;
Process p = new Process();
p.StartInfo = pInfo;
p.Start();
//p is null at this point if called application was already running
//i.e. Microsoft Word is re-used instead of starting a fresh copy
p.WaitForInputIdle();
p.WaitForExit();

有没有办法强制开始一个全新的进程,或者任何人都可以想出另一种方法来处理这个问题。我真的不希望用户能够在我的应用程序中执行任何其他操作,直到他们关闭被调用的进程,因为我需要知道他们是否在那个时间点编辑了该文件,而不是稍后当各种其他问题可能会蔓延。

【问题讨论】:

  • 编辑标签更通用,以便在更多提要上看到问题。

标签: c# winforms


【解决方案1】:

就我个人而言,我不确定我是否完全同意这种方法。显示模态表单可能会让您摆脱这种情况,但在大多数情况下,当您似乎很难找到解决方案时,更改您要解决的问题会很有帮助。

选项 1:

在这种情况下,我建议使用结帐/签入模型。这将允许用户将文件“签出”到他们的机器,然后在完成更新后签入。这有很多好处:

  • 他们可以一次编辑多个文档,并一次对多个文档执行签入操作。
  • 他们可以将 cmets 应用于签到。
  • 用户可以关闭他们的 PC,或者在离线的情况下继续处理他们的文档。
  • 用户可以在本地签出多个文档,然后将工作带回家。
  • 您无需尝试找出在打开文档时如果 PC 崩溃(或笔记本电脑电池耗尽)该怎么办,以及如何将它们重新组合在一起。

该模型也非常适合创建新文档并将其添加到数据库的概念。和签到一样。

您可以轻松提供报告,显示谁签出了哪些文档,以及他们的“工作副本”位置。

我承认,通常只有开发人员才对这种模型感到满意,并且您可能需要投资进行少量的再培训。我不认为设置一个自动提醒系统会在人们签出文档很长时间时向他们发送电子邮件。

选项 2:

使用 FileSystemWatcher 或等效工具监视文件。这将使您能够密切关注文件,并且当用户执行保存操作时,您可以提交到数据库。毕竟,只有当用户实际保存了您对更新数据库感兴趣的文件时,

【讨论】:

  • 选项一是个好主意,对遇到此问题的其他人有用;如果文档管理是应用程序的中心点。我会走那条路,但这是一个附带功能,模态对话框既简单又防弹,这是我必须支持的软件中我喜欢的两件事。 :)
  • 选项二我会非常谨慎地使用,我考虑过,但在网上遇到了很多关于它的麻烦的帖子,甚至它自己的文档也提到了缓冲区长度和长文件名的许多潜在问题等等。我认为对于我的目的来说太脆弱了,但可能对其他人有用。
【解决方案2】:

我不确定是否要启动一个新进程,但是您是否考虑过这种等待退出的逻辑:

while (Process.IsRunning) {}

基本上只是一个持有人循环,直到您的过程完成。

【讨论】:

  • 如果进程重用现有应用程序,则在调用 start 后立即为空。
【解决方案3】:

是的,订阅流程的退出事件并将 process.EnableRisingEvents 属性设置为 true。然后让您的应用程序在 Exited 事件被触发之前什么都不做!

关于强制使用新进程,我认为这是默认行为,我认为这取决于您调用的进程是否允许同时运行多个实例,这超出了您的范围控制...不幸的是。

祝你好运!

【讨论】:

  • 不幸的是两个问题:进程在调用 start 后立即为空,如果它重用并且如果他们已经为另一个文档打开了应用程序,我会被冻结,直到他们也关闭它。
  • 嗯...你有没有试过去掉最后两行:p.WaitForInputIdle(); p.WaitForExit(); ?然后订阅 Exited 并将 EnableRisingEvents 设置为 true,然后再调用 start()
【解决方案4】:

我认为您使用错误的方法来解决问题。如果您只处理文字文档,我相信您应该使用 COM 互操作来从您的应用程序中输入和控制文字。使用 COM,您可以在 word 中控制一切,您将能够在 word 中打开文档,并且您会知道用户何时关闭它。

【讨论】:

  • 不,这不仅仅是word文档,这只是一个例子,它可以是任何种文件。
【解决方案5】:

经过进一步研究并遇到许多提到 WaitForExit 的不可靠性和进程退出事件的帖子后,我想出了一个完全不同的解决方案:我启动进程并且不费心等待它,只需弹出一个模态对话框,用户可以在其中单击更新将临时文件夹文件更新回数据库,当他们编辑并保存临时文件或取消时。

这样它就在他们手中,我不必依赖 Process.Start 的变幻莫测。

感谢大家的帮助。

【讨论】:

    猜你喜欢
    • 2013-07-04
    • 2014-12-06
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 2018-10-08
    • 2016-03-23
    • 1970-01-01
    相关资源
    最近更新 更多