J'ai un problème avec une configuration client-serveur basée sur COM. Le serveur COM est écrit en C# (.NET 4.0) et fonctionne comme un serveur local (enregistré).
En fonction de l'application qui se connecte au serveur, les autres clients recevront une L'exécution du serveur a échoué (Exception de HRESULT : 0x80080005 (CO_E_SERVER_EXEC_FAILURE)
La question sous-jacente est expliquée ici (dans la section COM is integrity aware) . D'après ce que je comprends, le problème est dû au fait qu'une application élevée crée le serveur avec un niveau d'intégrité plus élevé. Lorsqu'une autre application non élevée se connecte ensuite, elle n'est pas autorisée à se connecter à la même instance. La même chose se produit lorsqu'une application non élevée crée le processus, suivi d'une application élevée qui se connecte.
J'ai essayé de mettre en œuvre la solution décrite sur le site Web de la Commission européenne. page : modifier le registre pour définir un descripteur de sécurité qui devrait permettre à tous les clients de se connecter. Il existe un exemple de code en C++, mais cela fait effectivement la même chose en .NET :
// Security Descriptor with NO_EXECUTE_UP
var sd = new RawSecurityDescriptor("O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)");
byte[] securityDescriptor = new Byte[sd.BinaryLength];
sd.GetBinaryForm(securityDescriptor, 0);
RegistryKey key = Registry.ClassesRoot.OpenSubKey("AppID\\{APP-ID-GUID}", true);
if (key == null)
{
key = Registry.ClassesRoot.CreateSubKey("AppID\\{APP-ID-GUID}");
}
using (key)
{
key.SetValue("LaunchPermission", securityDescriptor, RegistryValueKind.Binary);
}
Cependant, cela n'a pas l'effet escompté. Lorsque le deuxième client tente de créer une instance de l'objet en question, Windows essaie de lancer une instance distincte de mon serveur COM, mais ce dernier empêche l'exécution de deux instances sous le même utilisateur. Compte tenu des permissions que j'ai définies, je ne m'attendrais pas à ce qu'une deuxième instance soit lancée en premier lieu.
Étant donné que l'une des applications client est exécutée en IL moyen et l'autre en IL élevé, j'ai également expérimenté des variantes de l'option étiquette obligatoire comme :
O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;ME)
O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)(ML;;NX;;;ME)(ML;;NX;;;HI)
J'ai également essayé de définir le ROTFlags
à 0x1 (ROTFLAGS_ALLOWANYCLIENT) comme suggéré sur la page, toujours aucun changement de comportement.
J'ai établi que la valeur de registre LaunchPermission est utilisée d'une manière ou d'une autre. Je ne parviens pas à découvrir où elle est lue à l'aide de Process Monitor, mais lorsque j'utilise la commande dcomcnfg.exe
pour définir la même clé, je peux forcer le serveur à échouer le chargement en refusant les autorisations de lancement.
Je tiens à souligner que le processus de mon serveur n'a pas besoin d'être élevé. Comment puis-je faire en sorte que les processus élevés et non élevés puissent se connecter à une seule instance de serveur ?