一些系统正在关闭这个词

时间:2016-02-22 13:40:24

标签: vb.net office-interop

我在outlook addins中使用word interop api来读取word文件。

这对于使用Windows 8和Windows 10的Office 2010来说效果很好。但是对于一些带有办公室(x86)的Windows 7(x64)系统,我面临的问题是该词在某个时间后变得不可见。我想这种情况正在发生,因为当我看到任务管理器它只打开一个实例而我正在对单词执行以下操作

          Private Shared ObjwordApp As Word.Application
          ObjwordApp = New Word.Application()
          ObjwordApp.Visible = False 

谢谢

拉​​维

编辑: - 似乎 word会在出现上述问题的计算机上创建单个实例。这意味着如果我们从Outlook打开单词使用我们的互操作代码和使用用户手动干预添加。 两者都会创建winword.exe的单个实例。

我希望它能澄清这个问题。

1 个答案:

答案 0 :(得分:0)

历史上,Word和Excel等Office应用程序仅在Windows ROT中注册一个实例。默认行为是任何启动Office应用程序的后续操作都将被重新路由"到ROT中注册的实例。 (参考知识库文章https://support.microsoft.com/en-us/kb/316125https://support.microsoft.com/en-us/kb/238975

当代码使用GetActiveObject时,此行为也适用 - 它会获取在ROT中注册的实例,无论可能运行多少个Word实例。为了解决这个问题,如果你想确保你的代码共享它没有启动的实例,New关键字用于启动Word的新实例。申请对象。

棘手的部分是当ROT中没有注册现有的Word实例时。在这种情况下,当您启动一个新实例时,它将是在ROT中注册的实例,并且用户操作将倾向于拾取它,这可能导致冲突。 (参考知识库文章http://support.microsoft.com/kb/188546/

解决此问题的唯一方法是首先测试Word.Application的正在运行的实例(Process)是否可用。如果有,则使用New Word.Application将启动用户无法使用的Word实例。

如果没有可用的Word实例,您的代码需要首先启动一个使用的Word进程,让它为用户运行。然后,您的代码将启动第二个实例供自己使用。它不会在ROT中注册,因此当用户启动Word或双击文档时,将拾取第一个实例,而不是您的应用程序正在使用的实例。

请注意,在Windows + Office的最新版本中,发生了一些(未记录的)更改,这些更改会改变Word是否/如何从ROT中获取实例与启动新实例。这可能是您看到不同行为的原因。但是您需要在代码中构建变通方法,以确保没有冲突。

这是一个代码片段,说明了解决方法的原理

Process[] wdPcs = Process.GetProcessesByName("WinWord");
int nrWordInstances = wdPcs.Length - 1;
if (nrWordInstances >= 0)
{
  //To pick up other running instance, if you want
  //wdApp = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
  wdApp = new Word.Application();
}
else
{
  //The process that will be registered in the ROT
  //Allows use of command line switches to control how Word starts
  //https://support.office.com/en-us/article/Command-line-switches-for-Microsoft-Office-Word-2007-8be53d5f-9f13-4987-a91e-b272aac5d39d 
  //Note: new Word.Application() is also fine
  ProcessStartInfo psi = new ProcessStartInfo("winword.exe", "/w");
  Process wdProc = Process.Start(psi);

  //Instance to be used in the running code
  wdApp = new Word.Application();
}