1

I'm try to use Vista TaskDialog Wrapper and Emulator and I'm getting the following exception:

"Unable to find an entry point named 'TaskDialogIndirect' in DLL 'ComCtl32'."

...in a simple Console application:

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");

        PSTaskDialog.cTaskDialog.MessageBox(
            "MessageBox Title",
            "The main instruction text for the message box is shown here.",
            "The content text for the message box is shown here and the text willautomatically wrap as needed.",
            PSTaskDialog.eTaskDialogButtons.YesNo,
            PSTaskDialog.eSysIcons.Information
        );
     }
}

What am I doing wrong?

UPDATE:

Actually, I'm working on an Excel plugin using excel-dna. How can I control what dll Excel loads?

http://exceldna.codeplex.com/discussions/286990#post728888

Niels Bosma
  • 11,758
  • 29
  • 89
  • 148
  • 1
    Did you see http://stackoverflow.com/questions/719251/unable-to-find-an-entry-point-named-taskdialogindirect-in-dll-comctl32? – ordag Jan 21 '12 at 11:14
  • 3
    `in a simple Console application` is the key. That always loads the wrong version of ComCtl32.dll unless you provide a manifest. A Winforms app gets it right through Application.EnableVisualStyles(), WPF is iffy. – Hans Passant Jan 21 '12 at 13:17
  • I've tried the same steps as in http://stackoverflow.com/questions/719251/unable-to-find-an-entry-point-named-taskdialogindirect-in-dll-comctl32 but I'm getting the same error. – Niels Bosma Jan 22 '12 at 08:22
  • Solution: http://support.microsoft.com/kb/830033 – Sverrir Sigmundarson Oct 01 '14 at 13:46

2 Answers2

1

I haven't been at Office programming in a while, but my guess is that Excel loads both versions of comctl32, so you may need to use the Activation Context API to direct your code to the version that includes TaskDialog. Some ideas for fixing the problem (not solutions as such):

  • For test purposes, make a temporary enumeration of all modules in the active process - just to check if 6.10 is actually loaded (see below for a simple example of such an enumeration, albeit with a different intent).

  • Use the Activation Context API to get to the right version. Example of use from C# (for enabling themes by way of comctl32 6.0) here.

  • Alternatively (I never actually got this to work reliably in a WPF application I worked on), make a dialog abstraction class, which falls back to MessageDlg depending on the version available to you. There may be better ways of doing the check, but...:

FileVersionInfo version = ProcessUtils.GetLoadedModuleVersion("comctl32.dll");

if (version != null && version.FileMajorPart >= 6 && version.FileMinorPart >= 1)
{
   // We can use TaskDialog...
}
else
{
   // Use old style MessageBox
}

The enumeration of modules:

internal static FileVersionInfo GetLoadedModuleVersion(string name)
{
   Process process = Process.GetCurrentProcess();
   foreach (ProcessModule module in process.Modules)
   {
      if (module.ModuleName.ToLower() == name)
      {
         return module.FileVersionInfo;
      }
      return null;
   }
}
JimmiTh
  • 7,389
  • 3
  • 34
  • 50
-1

In addition to what all the others are saying: This error will disappear if you set the ForceEmulationMode on PSTaskDialog to true.

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
  • That workaround is not really fixing the problem just walking around it. – Niels Bosma Jan 31 '12 at 07:06
  • Yes - that's what a workaround does. It fixes the symptom without fixing the cause. I don't see this as a reason for a downvote, actually. However, as in most cases the OP won't be able to have his application load the correct version of the DLL, using the `ForceEmulationMode` will still allow him to use `PSTaskDialog` without getting an error. – Thorsten Dittmar Jan 31 '12 at 09:28