Question

J'ai du code pour activer / désactiver le service Windows Aero dans Vista et je souhaite l'exécuter dans un service Windows. Le code fonctionne dans une application autonome, mais lorsque je l'exécute à partir d'un service, rien ne se produit. Aucune erreur ou exception n'est générée.

Je réalise que le code en cours d'exécution dans un service a une portée différente de celle en cours d'exécution dans une application, mais dans ce cas, comment puis-je activer / désactiver Aero à partir du service? Est-ce seulement possible?

Voici le code sur lequel je travaille:

public static readonly uint DWM_EC_DISABLECOMPOSITION = 0;
public static readonly uint DWM_EC_ENABLECOMPOSITION = 1;

[DllImport("dwmapi.dll", EntryPoint="DwmEnableComposition")]
protected static extern uint Win32DwmEnableComposition(uint uCompositionAction);

public static bool EnableAero() 
{
    Win32DwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
}

Modifier:

Il se trouve que l'appel DwmEnableComposition renvoie HRESULT 0x80070018 ou ERROR_BAD_LENGTH. Cela ressemble à une erreur étrange, car le code fonctionne sans être exécuté en tant que service.

J'ai aussi essayé de changer le code en entier, mais j'ai obtenu le même résultat. Il définit la station de travail et le bureau Windows, et cela semble être correct, mais l'appel à DwmEnableComposition entraîne la même erreur. Je n'ai pas inclus les déclarations PInvoke par souci de brièveté.

    protected override void OnStop()
    {
        IntPtr winStation = OpenWindowStation("winsta0", true, 0x10000000 /* GENERIC_ALL */);
        if (winStation == null || winStation.ToInt32() == 0)
        {
            String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
        }

        if (!SetProcessWindowStation(winStation))
        {
            String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
        }

        uint thread = GetCurrentThreadId();

        IntPtr hdesk = OpenInputDesktop(0, false, 0x10000000 /* GENERIC_ALL */);
        if (hdesk == null || hdesk.ToInt32() == 0)
        {
            String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
        }

        if (!SetThreadDesktop(hdesk))
        {
            String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
        }

        uint result = Win32DwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
        if (result != 0)
        {
            String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
        }
    }
Était-ce utile?

La solution

J'avais le même code d'erreur lors de la création de WPF FlowDocuments via un service exécuté sous Vista 64 bits. Après avoir fouillé, je peux parcourir cette publication sur Microsoft Connect , qui souligne que

  

"... Le problème est dû à un problème d'interopérabilité avec le DWM ..."

et

  

"... cela résoudra le crash de WPF dans tous les cas   services, y compris IIS7 ... "

Voici le lien direct vers les téléchargements du correctif logiciel; KB 959209

Ceci corrigeait nos problèmes d'exécution de tests unitaires via CruiseControl.Net (CCNet) sous Vista 64 bits. Les tests étaient satisfaisants s’ils ne passaient pas par un service.

Autres conseils

Je n'en suis pas certain, mais vous devez peut-être associer le processus de votre service au poste de travail actuel pour que cela fonctionne?

Assurez-vous que votre service peut interagir avec le bureau. Ensuite, utilisez SetThreadDesktop () pour définir le bureau. pour le fil de service transmettant au bureau un descripteur appelé "Par défaut".

Je ne l'ai pas essayé et je ne peux pas garantir que cela fonctionnera. Mais cela pourrait être quelque chose à essayer?

Bonne chance:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top