首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中使用TaskDialog时的EntryPointNotFoundException

在C#中使用TaskDialog时的EntryPointNotFoundException
EN

Stack Overflow用户
提问于 2009-10-23 17:34:22
回答 3查看 3.7K关注 0票数 9

我使用下面的代码来调用TaskDialog。

代码语言:javascript
复制
    [DllImport("ComCtl32", CharSet = CharSet.Unicode, PreserveSig = false)]
    internal static extern void TaskDialogIndirect(
        [In] ref TASKDIALOGCONFIG pTaskConfig,
        [Out] out int pnButton,
        [Out] out int pnRadioButton,
        [Out] out bool pfVerificationFlagChecked);

但是,我得到异常“无法在DLL‘ComCtl32’中找到名为'TaskDialogIndirect‘的入口点”。

我把this code带走了。我使用的是Windows7 x64 (RC)。

我做错了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-10-23 17:51:30

除了这是一个vista功能之外,没有其他功能。

更新:此问题与并行程序集有关:这些函数仅在comctl32.dll版本6中存在,但出于兼容性原因,除非您另行说明,否则Vista将加载更早的版本。大多数人(包括我)一直采用的方法是使用清单。事实证明,这很棘手,而且可能不是正确的解决方案,特别是如果您正在编写的是一个库:您不一定要强制整个应用程序使用公共控件6。

正确的解决方案是在调用Vista之一时推送new activation上下文。激活上下文将使用正确版本的comctl32.dll,而不会影响应用程序的其余部分,并且不需要任何清单。

幸运的是,这很容易do.Some已经存在的MS Knowledgebase的完整代码。文章中的代码(KB 830033)照原样做了这件事。

可供选择的托管应用编程接口:Vista的TaskDialog和TaskDialogIndirect的完整包装可以在这里找到:

http://code.msdn.microsoft.com/WindowsAPICodePack

对于WPF,请使用以下内容:

http://code.msdn.microsoft.com/VistaBridge下载“Interop”下载后,打开项目,然后构建它(如果您想查看所有代码,请检查\VistaBridge或\Interop文件夹中的文件)。现在,您可以从VistaBridge\bin\debug\中获取DLL,并在项目中添加对它的引用,还必须为每个不同的VistaBridge模块添加一条using语句。例如:

使用Microsoft.SDK.Samples.VistaBridge.Interop或.Library或.Properties或.Services -取决于您的需求。

VistaBridge项目包括许多其他Vista功能的应用编程接口(例如TaskDialog、Vista和OpenFile对话框,当然还有航空玻璃效果)。要尝试这些功能,请运行VistaBridge项目。

票数 9
EN

Stack Overflow用户

发布于 2013-07-15 12:35:19

使用任务对话框需要Windows公共控件DLL(ComCtl32.dll)版本6!出于兼容性原因,默认情况下,应用程序不绑定到此版本。绑定到版本6的一种方法是在可执行文件(名为YourAppName.exe.manifest)旁边放置一个清单文件,其中包含以下内容:

代码语言:javascript
复制
 <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
  </dependency>

如果您不想要额外的独立文件,也可以将此清单作为Win32资源嵌入到可执行文件中(名称为RT_MANIFEST,ID设置为1)。如果您将清单文件与项目的属性相关联,则Visual Studio可以为您完成此工作。

票数 3
EN

Stack Overflow用户

发布于 2019-02-21 15:47:14

基于almog.ori的回答(它得到了一些孤立的链接),我对链接的代码做了一个小修改,我困惑了好几天:

MS Knowledgebase帮助(Archiv),完整的代码,由我所做的领养:

代码语言:javascript
复制
using System.Runtime.InteropServices;
using System;
using System.Security;
using System.Security.Permissions;
using System.Collections;
using System.IO;
using System.Text;

namespace MyOfficeNetAddin
{
    /// <devdoc>
    ///     This class is intended to use with the C# 'using' statement in
    ///     to activate an activation context for turning on visual theming at
    ///     the beginning of a scope, and have it automatically deactivated
    ///     when the scope is exited.
    /// </devdoc>

[SuppressUnmanagedCodeSecurity]
internal class EnableThemingInScope : IDisposable
{
   // Private data
   private IntPtr cookie; // changed cookie from uint to IntPtr
   private static ACTCTX enableThemingActivationContext;
   private static IntPtr hActCtx;
   private static bool contextCreationSucceeded = false;

   public EnableThemingInScope(bool enable)
   {
     if (enable)
     {
       if (EnsureActivateContextCreated())
       {
         if (!ActivateActCtx(hActCtx, out cookie))
         {
           // Be sure cookie always zero if activation failed
           cookie = IntPtr.Zero;
         }
       }
     }
  }

  // Finalizer removed, that could cause Exceptions
  // ~EnableThemingInScope()
  // {
  //    Dispose(false);
  // }

  void IDisposable.Dispose()
  {
     Dispose(true);
     GC.SuppressFinalize(this);
  }

  private void Dispose(bool disposing)
  {
     if (cookie != IntPtr.Zero)
     {
        if (DeactivateActCtx(0, cookie))
        {
           // deactivation succeeded...
           cookie = IntPtr.Zero;
        }
     }
  }

  private bool EnsureActivateContextCreated()
  {
   lock (typeof(EnableThemingInScope))
   {
    if (!contextCreationSucceeded)
    {
     // Pull manifest from the .NET Framework install
     // directory

     string assemblyLoc = null;

     FileIOPermission fiop = new FileIOPermission(PermissionState.None);
     fiop.AllFiles = FileIOPermissionAccess.PathDiscovery;
     fiop.Assert();
     try
     {
        assemblyLoc = typeof(Object).Assembly.Location;
     }
     finally
     { 
        CodeAccessPermission.RevertAssert();
     }

     string manifestLoc = null;
     string installDir = null;
     if (assemblyLoc != null)
     {
        installDir = Path.GetDirectoryName(assemblyLoc);
        const string manifestName = "XPThemes.manifest";
        manifestLoc = Path.Combine(installDir, manifestName);
     }

     if (manifestLoc != null && installDir != null)
     {
         enableThemingActivationContext = new ACTCTX();
         enableThemingActivationContext.cbSize = Marshal.SizeOf(typeof(ACTCTX));
         enableThemingActivationContext.lpSource = manifestLoc;

         // Set the lpAssemblyDirectory to the install
         // directory to prevent Win32 Side by Side from
         // looking for comctl32 in the application
         // directory, which could cause a bogus dll to be
         // placed there and open a security hole.
         enableThemingActivationContext.lpAssemblyDirectory = installDir;
         enableThemingActivationContext.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID; 

         // Note this will fail gracefully if file specified
         // by manifestLoc doesn't exist.
         hActCtx = CreateActCtx(ref enableThemingActivationContext);
         contextCreationSucceeded = (hActCtx != new IntPtr(-1));
     }
    }

    // If we return false, we'll try again on the next call into
    // EnsureActivateContextCreated(), which is fine.
    return contextCreationSucceeded;
   }
  }

  // All the pinvoke goo...
  [DllImport("Kernel32.dll")]
  private extern static IntPtr CreateActCtx(ref ACTCTX actctx);

  // changed from uint to IntPtr according to 
  // https://www.pinvoke.net/default.aspx/kernel32.ActiveActCtx
  [DllImport("Kernel32.dll", SetLastError = true)]
  [return: MarshalAs(UnmanagedType.Bool)]
  private static extern bool ActivateActCtx(IntPtr hActCtx, out IntPtr lpCookie);

  // changed from uint to IntPtr according to 
  // https://www.pinvoke.net/default.aspx/kernel32.DeactivateActCtx
  [DllImport("Kernel32.dll", SetLastError = true)]
  [return: MarshalAs(UnmanagedType.Bool)]
  private static extern bool DeactivateActCtx(int dwFlags, IntPtr lpCookie);

  private const int ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004;

  private struct ACTCTX 
  {
     public int       cbSize;
     public uint      dwFlags;
     public string    lpSource;
     public ushort    wProcessorArchitecture;
     public ushort    wLangId;
     public string    lpAssemblyDirectory;
     public string    lpResourceName;
     public string    lpApplicationName;
  }
 }
}

然后我就这样用它了:

代码语言:javascript
复制
using (new EnableThemingInScope(true))
{
    // The call all this mucking about is here for.
    VistaUnsafeNativeMethods.TaskDialogIndirect(ref config, out result, out radioButtonResult, out verificationFlagChecked);
 }

WPF Task Dialog Wrapper on GitHub提供的TaskDialogInterop.cs

有关EnableThemingInScope的终结器中可能的SEHException的更多信息,请参阅此Question on SO

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

https://stackoverflow.com/questions/1612351

复制
相关文章

相似问题

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