在没有主窗口的情况下通过它的进程名称获取Windows标题

时间:2013-05-15 10:11:34

标签: c# user32

我有一个问题我正试图通过它的进程名称获取一个窗口的标题,我不能在这里做我尝试过的事情:

Process[] p = Process.GetProcessesByName("Acrobat");
Console.WriteLine(p[0].MainWindowTitle);
Console.ReadLine();

但问题是我只能在相关进程确实有一个主窗口时才能获得它。我怎样才能让它发挥作用?

主要目标是我有一个名为BringToFront()的方法 但是这种方法需要一个标题名称,即“然后是PDF.pdf - Adob​​e Acrobat Pro(是的,acrobat运行时打开了pdf)” 我想把我的Acrobat窗口带到前面.. 但为此,我需要窗口的名称,因为我的方法是要求标题。  以下是整个代码:

class Program
{
    [DllImport("User32.dll")]
    public static extern Int32 SetForegroundWindow(int hWnd);

    [DllImport("user32.dll")]
    public static extern int FindWindow(string lpClassName, string lpWindowName);

    private static void BringToFront(string className, string CaptionName)
    {
        SetForegroundWindow(FindWindow(className, CaptionName));
    }

    static void Main(string[] args)
    {
        // BringToFront("Acrobat", "mypdf.pdf - Adobe Acrobate Pro");
        Process[] p = Process.GetProcesses();
        foreach (var process in p)
        {
           Console.WriteLine(process.MainWindowTitle);
        }
        Console.ReadLine();
    }
}

3 个答案:

答案 0 :(得分:2)

您是否阅读过该手册,以下内容是否适用?

  

只有当进程具有图形界面时,进程才有与其关联的主窗口。如果关联的进程没有主窗口(以便MainWindowHandle为零),则MainWindowTitle为空字符串(“”)。如果您刚刚启动了一个进程并希望使用其主窗口标题,请考虑使用WaitForInputIdle方法来允许进程完成启动,确保已创建主窗口句柄。否则,系统会抛出异常。

答案 1 :(得分:0)

如果使用GetProcesses()将它们全部转储出来,则窗口标题将显示为“Adobe Reader”,前缀为PDF的名称(如果已打开)。所以你可能需要这样做并改为使用数组。

例如,如果我打开UserManual.pdf并运行下面的代码,它会在控制台上显示 UserManual.pdf - Adob​​e Reader

        Process[] p = Process.GetProcesses();
        String Title = String.Empty;
        for (var i = 0; i < p.Length; i++)
        {
            Title = p[i].MainWindowTitle;

            if (Title.Contains(@"Adobe"))
                Console.WriteLine(Title);
        }

答案 2 :(得分:0)

一种可能的解决方案是枚举所有顶级窗口并选择您感兴趣的窗口。在您的情况下,这将是所有具有AcrobatSDIWindow类的窗口以及以您的文档名称开头的窗口标题。

class Program
{
    public class SearchData
    {
        public string ClassName { get; set; }
        public string Title { get; set; }

        private readonly List<IntPtr> _result = new List<IntPtr>();
        public List<IntPtr> Result
        {
            get { return _result; }
        }
    }

    [DllImport("User32.dll")]
    public static extern Int32 SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, ref SearchData data);

    private delegate bool EnumWindowsProc(IntPtr hWnd, ref SearchData data);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    public static bool EnumProc(IntPtr hWnd, ref SearchData searchData)
    {
        var sbClassName = new StringBuilder(1024);
        GetClassName(hWnd, sbClassName, sbClassName.Capacity);
        if (searchData.ClassName == null || Regex.IsMatch(sbClassName.ToString(), searchData.ClassName))
        {
            var sbWindowText = new StringBuilder(1024);
            GetWindowText(hWnd, sbWindowText, sbWindowText.Capacity);
            if (searchData.Title == null || Regex.IsMatch(sbWindowText.ToString(), searchData.Title))
            {
                searchData.Result.Add(hWnd);
            }
        }
        return true;
    }

    static void Main(string[] args)
    {
        var searchData = new SearchData 
            { 
                ClassName = "AcrobatSDIWindow", 
                Title = "^My Document\\.pdf.*"
            };

        EnumWindows(EnumProc, ref searchData);

        var firstResult = searchData.Result.FirstOrDefault();
        if (firstResult != IntPtr.Zero)
        {
            SetForegroundWindow(firstResult);
        }
    }
}