Vista TaskDialog Wrapper: не удалось найти точку входа с именем «TaskDialogIndirect» в DLL «ComCtl32»

Я пытаюсь использовать Vista TaskDialog Wrapper и эмулятор, и я получаю следующее исключение:

«Невозможно найти точку входа с именем« TaskDialogIndirect »в библиотеке DLL« ComCtl32 »».

... в простом консольном приложении:

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
        );
     }
}

Что я делаю неправильно?

ОБНОВИТЬ:

Собственно, я работаю над плагином Excel с использованием excel-dna. Как я могу контролировать, какие DLL загружает Excel?

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


person Niels Bosma    schedule 21.01.2012    source источник
comment
Вы видели, что stackoverflow.com/questions/719251/?   -  person ordag    schedule 21.01.2012
comment
in a simple Console application - это ключ. Это всегда загружает неправильную версию ComCtl32.dll, если вы не предоставите манифест. Приложение Winforms получает это прямо через Application.EnableVisualStyles (), WPF ненадежен.   -  person Hans Passant    schedule 21.01.2012
comment
Я пробовал те же шаги, что и в stackoverflow.com/questions/719251/, но я получаю ту же ошибку.   -  person Niels Bosma    schedule 22.01.2012
comment
Решение: support.microsoft.com/kb/830033   -  person Sverrir Sigmundarson    schedule 01.10.2014


Ответы (2)


Я давно не занимался программированием Office, но предполагаю, что Excel загружает обе версии comctl32, поэтому вам может потребоваться использовать API контекста активации, чтобы направить ваш код в версию, которая включает TaskDialog. Некоторые идеи по устранению проблемы (не решения как таковые):

  • В целях тестирования сделайте временное перечисление всех модулей в активном процессе - просто чтобы проверить, действительно ли 6.10 загружен (см. Ниже простой пример такого перечисления, хотя и с другим намерением).

  • Используйте API контекста активации, чтобы перейти к правильная версия. Пример использования из C # (для включения тем с помощью comctl32 6.0) здесь.

  • В качестве альтернативы (у меня никогда не получалось, чтобы это работало надежно в приложении WPF, над которым я работал), создайте класс абстракции диалога, который возвращается к MessageDlg в зависимости от доступной вам версии. Могут быть более эффективные способы проверки, но ...:

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

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

Перечень модулей:

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;
   }
}
person JimmiTh    schedule 30.01.2012

В дополнение к тому, что говорят все остальные: эта ошибка исчезнет, ​​если вы установите ForceEmulationMode на PSTaskDialog на true.

person Thorsten Dittmar    schedule 30.01.2012
comment
Этот обходной путь на самом деле не решает проблему, просто обходя ее. - person Niels Bosma; 31.01.2012
comment
Да - это то, что делает обходной путь. Он устраняет симптом, не устраняя причину. На самом деле, я не вижу в этом причины для отрицательного голоса. Однако, поскольку в большинстве случаев OP не сможет заставить свое приложение загружать правильную версию DLL, использование ForceEmulationMode по-прежнему позволит ему использовать PSTaskDialog без получения ошибки. - person Thorsten Dittmar; 31.01.2012