0

In the following code, why does user32 cause an error?

I thought that by adding [DllImport("user32.dll", CharSet = CharSet.Unicode)] above a method body that I could then make statements like user32.IsWindowVisible(hWnd) but the user32 portion of that line of code is causing an error.

Here is a full example. If you copy paste this in to visual studio in to a class file you will see the errors:

using System.Collections.Generic;
using System.Runtime.InteropServices;
using System;
using System.Text;

namespace Pinvoke.Automation.Debug.Examples
{

   internal static class ExampleEnumDesktopWindows
    {

        public delegate bool EnumDelegate(IntPtr hWnd, int lParam);


        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsWindowVisible(IntPtr hWnd);



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


        [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows",
        ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);

       [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
        static void DoExample()
        {
            var collection = new List<string>();
            user32.EnumDelegate filter = delegate(IntPtr hWnd, int lParam)
            {
                StringBuilder strbTitle = new StringBuilder(255);
                int nLength = user32.GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1);
                string strTitle = strbTitle.ToString();

                if (user32.IsWindowVisible(hWnd) && string.IsNullOrEmpty(strTitle) == false)
                {
                    collection.Add(strTitle);
                }
                return true;
            };

            if (user32.EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero))
            {
                foreach (var item in collection)
                {
                    Console.WriteLine(item);
                }
            }
            Console.Read();
        }
    }
}
sapbucket
  • 6,795
  • 15
  • 57
  • 94
  • 1
    *"why does user32 cause an error"* ... Which error? Be specific; we can't see your monitor. – cdhowie Sep 03 '14 at 23:09
  • 2
    "I thought that by adding [DllImport...] above a method body that I could then make statements like user32.IsWindowVisible(hWnd)" - nope, that's not how it works at all.. You've declared your externs, just refer to them directly. They don't need `user32.` at all. – Blorgbeard Sep 03 '14 at 23:11
  • 1
    And it doesn't make sense to add `[DllImport]` on a non extern method. – Blorgbeard Sep 03 '14 at 23:11

2 Answers2

2

P/invoke needs the DLL name and EntryPoint property, both specified in the DllImport attribute.

Your code doesn't care about these. It just uses the identifier you used when declaring the DllImport-annotated method.

In your case that identifier is IsWindowVisible, and the fully-qualified name is Pinvoke.Automation.Debug.Examples.ExampleEnumDesktopWindows.IsWindowVisible.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

The DllImport attribute must be specified on a method marked 'static' and 'extern', so therefore you can't have it on your DoExample() method.

Try removing it from that method, and remove user32. from the method calls inside your DoExample() function.

Rufus L
  • 36,127
  • 5
  • 30
  • 43