J'utilise le WindowsAPICodePack pour TaskDialog. Lorsque j'essaie d'afficher la boîte de dialogue, elle indique qu'elle doit charger la version 6 de comctl32.dll. J'ai donc ajouté la version 6 à app.manifest et j'ai essayé de l'exécuter. Toujours pas de chance. Je suis allé au dossier Déboguer et ai couru le programme sans Visual Studio et cela fonctionne très bien. Je devine que Visual Studio n'utilise pas le fichier manifeste ... Je me demandais s'il y avait un moyen de le faire faire.C#: comctl32.dll version 6 dans le débogueur
Répondre
Rob pol86, votre code lance SEHExceptions, car les signatures pour ActivateActCtx et DeactivateActCtx ne sont pas correctes. Vous devez utiliser UIntPtr
au lieu de uint
pour le lpCookie.
Par conséquent, le bon code pour EnableThemingInScope.cs serait:
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;
namespace Microsoft.WindowsAPICodePack.Dialogs
{
/// http://support.microsoft.com/kb/830033
/// <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 UIntPtr cookie;
private static ACTCTX enableThemingActivationContext;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
private static IntPtr hActCtx;
private static bool contextCreationSucceeded = false;
public EnableThemingInScope(bool enable)
{
cookie = UIntPtr.Zero;
if (enable && OSFeature.Feature.IsPresent(OSFeature.Themes))
{
if (EnsureActivateContextCreated())
{
if (!ActivateActCtx(hActCtx, out cookie))
{
// Be sure cookie always zero if activation failed
cookie = UIntPtr.Zero;
}
}
}
}
~EnableThemingInScope()
{
Dispose();
}
void IDisposable.Dispose()
{
Dispose();
GC.SuppressFinalize(this);
}
private void Dispose()
{
if (cookie != UIntPtr.Zero)
{
try
{
if (DeactivateActCtx(0, cookie))
{
// deactivation succeeded...
cookie = UIntPtr.Zero;
}
}
catch (SEHException)
{
//Hopefully solved this exception
}
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2002:DoNotLockOnObjectsWithWeakIdentity")]
private static 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);
[DllImport("Kernel32.dll")]
private extern static bool ActivateActCtx(IntPtr hActCtx, out UIntPtr lpCookie);
[DllImport("Kernel32.dll")]
private extern static bool DeactivateActCtx(uint dwFlags, UIntPtr 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;
}
}
}
Cette page décrit comment ajouter un manifeste personnalisé à votre projet afin de dire Windows pour charger la nouvelle comctl32.dll (version 6.0):
Votre manifeste ont la bonne dépendance sur comctl32.dll? Avez-vous intégré le manifeste créé?
J'ai le même problème avec Visual Studio en mode débogage. Jusqu'à présent, je n'ai pas trouvé de solution de contournement, cela fonctionne très bien en mode Release.
J'ai récemment rencontré ce problème lors du débogage du code avec TaskDialogDemo dans le CodePack. C'est comme ça que je l'ai réparé. Le problème avec l'utilisation de ceci est que si j'ouvre deux ou trois boîtes de dialogue il lance une SEHException, que je n'ai pas trouvée comment réparer. Alors acheteur méfiez-vous.
Ajouter core \ Interop \ TaskDialogs \ EnableThemingInScope.cs:
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;
namespace Microsoft.WindowsAPICodePack.Dialogs {
/// http://support.microsoft.com/kb/830033
/// <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 uint cookie;
private static ACTCTX enableThemingActivationContext;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
private static IntPtr hActCtx;
private static bool contextCreationSucceeded = false;
public EnableThemingInScope(bool enable) {
cookie = 0;
if (enable && OSFeature.Feature.IsPresent(OSFeature.Themes)) {
if (EnsureActivateContextCreated()) {
if (!ActivateActCtx(hActCtx, out cookie)) {
// Be sure cookie always zero if activation failed
cookie = 0;
}
}
}
}
~EnableThemingInScope() {
Dispose();
}
void IDisposable.Dispose() {
Dispose();
GC.SuppressFinalize(this);
}
private void Dispose() {
if (cookie != 0) {
try {
if (DeactivateActCtx(0, cookie)) {
// deactivation succeeded...
cookie = 0;
}
} catch (SEHException) {
// Robpol86: I don't know how to fix this!
}
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2002:DoNotLockOnObjectsWithWeakIdentity")]
private static 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);
[DllImport("Kernel32.dll")]
private extern static bool ActivateActCtx(IntPtr hActCtx, out uint lpCookie);
[DllImport("Kernel32.dll")]
private extern static bool DeactivateActCtx(uint dwFlags, uint 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;
}
}
}
Puis, dans de base \ Interop \ TaskDialogs \ NativeTaskDialog.cs en ligne 93 (ci-dessus HResult hresult = TaskDialogNativeMethods.TaskDialogIndirect) faire ressembler la section comme ceci (à la fin vous aurez trois nouvelles lignes):
- 1. Détection de la version COMCTL32 dans .NET
- 2. C++ dll dans le programme C
- 3. Impossible de trouver un point d'entrée nommé 'TaskDialogIndirect' dans 'comctl32' DLL
- 4. Numéro de version d'une dll dans .NET
- 5. Comment mettre à jour le contrôle commun dans Windows 2000 vers la version 6
- 6. Ignorer le code source dans le débogueur
- 7. Lire une version non .NET DLL de C#?
- 8. Débogueur intégrable pour C++
- 9. Inclure automatiquement le numéro de version DLL dans le nom de fichier dans Visual Studio
- 10. programme d'interruption dans le débogueur lorsque C++ exception est levée
- 11. Objective-C: variables d'instance hors de portée dans le débogueur
- 12. Pause dans le débogueur C# pour diviser par zéro
- 13. vcredist_x86.dll et la version 8.0.50727.4053
- 14. DLL de site Web ASP.NET: version de débogage et version
- 15. Comment lancer le débogueur IE8 avec le débogueur; commande
- 16. Comment puis-je intégrer une version dans une DLL?
- 17. webbrowser désactiver le débogage de script dans Visual Basic 6
- 18. Comprendre le Débogueur Symbolique
- 19. SharePoint attachant le débogueur
- 20. Comment arrêter le débogueur Ruby (comme CTL-C de GDB)
- 21. informations Version Assemblée pour Récupération de plusieurs DLL dans msbuild
- 22. Prototype.js Exception dans le navigateur IE (Version 6) lors du chargement de la page Web
- 23. Maintenir la version correcte pour une DLL dll référencée dans un projet .NET
- 24. Ressource de version dans DLL non visible avec le bouton droit
- 25. problème de chargement d'une DLL dans le fichier .c
- 26. Version Unicode prise en charge par Java 6
- 27. Visual Studio 6 VC++ Version du projet - comment l'incrémenter?
- 28. Convertir notre application de la version Java 6 à 5,
- 29. Problème de débogueur à C# Express - 2008
- 30. Crash C# lors du chargement C++ dll
Cheers, c'est la bonne réponse. Pas besoin de changer de manifeste avec ça. –
+1 Pour une réponse correcte. Pour référence future, j'ai eu une implémentation de cookie uint cassée similaire à partir de cet article de base de connaissances msdn: https://support.microsoft.com/en-us/kb/830033 juste pour plus de clarté: je pouvais créer la portée, mais j'ai eu un SEH Exception sur DeactivateActCtx. un débogage supplémentaire a révélé que c'était le code d'erreur 6, qui est ERROR_INVALID_HANDLE car le cookie n'a pas pu être utilisé pour désactiver correctement le contexte en raison de son mauvais type. – Samuel
Merci! J'avais des problèmes avec comctl32.dll lors de la publication ClickOnce, et cela a résolu – dariusc