首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Office互操作获取特定窗口句柄

使用Office互操作获取特定窗口句柄
EN

Stack Overflow用户
提问于 2011-12-30 05:33:47
回答 6查看 7.8K关注 0票数 6

我正在使用Office互操作创建一个新的Word实例,方法如下:

代码语言:javascript
运行
复制
var word = Microsoft.Office.Interop.Word.Application();
word.Visible = true;
word.Activate;

我可以像这样得到一个窗口句柄:

代码语言:javascript
运行
复制
var wordHandle = Process.GetProcessesByName("winword")[0].MainWindowHandle;

问题是,代码的工作原理是假设没有其他Word实例在运行。如果有多个,它不能保证返回的句柄是我启动的实例的句柄。在检测到来自我的对象的WindowActivate事件后,我尝试使用GetForegroundWindow,但这都是在一个设置为作为最顶层窗口运行的WPF应用程序中运行的,所以我只获得了WPF窗口的句柄。有没有其他方法来获得我的word实例的句柄?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-12-30 05:56:12

不知道为什么你需要Word的句柄,但我以前做过的一种方法是实际更改Word窗口标题并搜索它。我这样做是因为我想在控件中承载Word应用程序,但那是另一回事了。:)

代码语言:javascript
运行
复制
  var word = new Microsoft.Office.Interop.Word.Application(); 
  word.Visible = true; 
  word.Activate();
  word.Application.Caption = "My Word";

  foreach( Process p in Process.GetProcessesByName( "winword" ) )
  {
    if( p.MainWindowTitle == "My Word" )
    {
      Debug.WriteLine( p.Handle.ToString() );
    }
  }

一旦你得到了句柄,你可以恢复你喜欢的标题。

票数 6
EN

Stack Overflow用户

发布于 2014-05-09 05:39:25

我将保留我选择的正确答案,因为这是我在写这篇文章时发现的问题。从那以后,我需要为一个不同的项目做一些类似的事情,并发现尝试更新应用程序标题似乎不太可靠(Office 2013与2010?谁知道呢...)。这是我想出的一个新的解决方案,可以让窗口标题保持不变。

代码语言:javascript
运行
复制
var startingProcesses = Process.GetProcessesByName("winword").ToList();

var word = new Microsoft.Office.Interop.Word.Application(); 

var allProcesses = Process.GetProcessesByName("winword").ToList();

var processDiff = allProcesses.Except(startingProcesses, new ProcessComparer());

var handle = processDiff.First().MainWindowHandle;

这将使用以下自定义比较器来确保进程匹配(找到here)。

代码语言:javascript
运行
复制
class ProcessComparer : IEqualityComparer<Process>
{
    public bool Equals(Process x, Process y)
    {
        if (ReferenceEquals(x, y))
        {
            return true;
        }

        if (x == null || y == null)
        {
            return false;
        }

        return x.Id.Equals(y.Id);
    }

    public int GetHashCode(Process obj)
    {
        return obj.Id.GetHashCode();
    }
}
票数 3
EN

Stack Overflow用户

发布于 2011-12-30 06:33:20

您已经获得了所有Word进程的列表。您可以遍历此列表,获取每个进程的父ID,并匹配当前进程,即创建Word实例的您自己的应用程序。这大致是我的想法:

代码语言:javascript
运行
复制
IntPtr getChildProcess(string childProcessName)
{
    var currentProcess = Process.GetCurrentProcess();

    var wordProcesses = Process.GetProcessesByName(childProcessName);
    foreach (var childProcess in wordProcesses)
    {
        var parentProcess = ProcessExtensions.Parent(childProcess);
        if (currentProcess.Id == parentProcess.Id)
            return currentProcess.Handle;
    }

    return IntPtr.Zero;
}

this excellent response中的ProcessExtensions类在之前的文章中可用。我在自己的代码中使用了这个类,没有收到任何抱怨。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8673726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档