42 votes

Extension de shell Windows avec C #

Je voulais écrire une simple extension de shell Windows à ajouter au menu contextuel, et C # est le langage que j'utilise le plus ces jours-ci. Est-ce un choix décent pour une extension de shell? Les interfaces sont-elles faciles d'accès avec? Y a-t-il des frais supplémentaires qui ralentissent le menu?

Quelqu'un a-t-il de bons conseils pour commencer?

26voto

GSerg Points 33571

Raymond post: Ne pas écrire dans le processus d'extensions de shell dans le code managé.


Un suivi récent: Maintenant que la version 4 de la .NET Framework prend en charge le processus de side-by-side temps de fonctionnement, il est maintenant de bon à écrire des extensions de shell dans le code managé?

La ligne du bas est, non, il n'est pas correct:

Les Orientations pour la mise en œuvre dans les processus d'extensions a été révisé, et il continue la recommandation contre l'écriture d'extensions de shell et Internet Explorer extensions (et d'autres types de processus extensions) dans le code géré, même si vous utilisez la version 4 ou supérieure.

16voto

ladenedge Points 4986

Au risque de ressembler à un complice, EZShellExtensions est un merveilleux (mais non libre) cadre pour l'extension d'environnement de développement en C#. Vous pouvez écrire une simple extension des menus contextuels avec environ 20 lignes de code, et le meilleur de tous, sans avoir à jouer avec les interfaces COM. Mon entreprise utilise (et leur extension d'espace de noms framework) pour un ensemble d'extensions actuellement utilisé par des dizaines de milliers de clients et, pour ce que ça vaut, nous n'avons jamais eu un problème avec le CLR conflit décrit ci-dessus.

Voici un petit exemple pour montrer comment il est facile:

[Guid("00000000-0000-0000-0000-000000000000"), ComVisible(true)]
[TargetExtension(".txt", true)]
public class SampleExtension : ContextMenuExtension
{
   protected override void OnGetMenuItems(GetMenuitemsEventArgs e)
   {
      e.Menu.AddItem("Sample Extension", "sampleverb", "Status/help text");
   }

   protected override bool OnExecuteMenuItem(ExecuteItemEventArgs e)
   {
      if (e.MenuItem.Verb == "sampleverb")
         ; // logic
      return true;
   }

   [ComRegisterFunction]
   public static void Register(Type t)
   {
      ContextMenuExtension.RegisterExtension(typeof(SampleExtension));
   }

   [ComUnregisterFunction]
   public static void UnRegister(Type t)
   {
      ContextMenuExtension.UnRegisterExtension(typeof(SampleExtension));
   }
}

16voto

Ehsan Mohammadi Points 71

Conseils pour la mise en Œuvre Dans les Processus d'Extensions

Des Conflits De Version

Une version conflits peuvent survenir par le biais d'un moteur d'exécution qui ne prend pas en charge le chargement de plusieurs versions du moteur d'exécution au sein d'un seul processus. Les Versions de la CLR antérieures à la version 4.0 entrent dans cette catégorie. Si le chargement d'une version d'un moteur d'exécution empêche le chargement des autres versions de la même exécution, ce qui peut créer un conflit si l'application hôte ou un autre processus d'extension utilise un conflit de version. Dans le cas d'un conflit de version avec une autre extension processus, le conflit peut être difficile à reproduire, car l'échec exige la présence d'un conflit d'extensions et le mode de défaillance dépend de l'ordre dans lequel les conflits d'extensions sont chargées.

Envisager un processus d'extension de l'écrit à l'aide d'une version du CLR antérieures à la version 4.0. Toutes les applications sur l'ordinateur qui utilise un fichier à Ouvrir la boîte de dialogue pourrait avoir la boîte de dialogue du code managé et de son cortège de CLR dépendance chargés dans l'application du processus. L'application ou l'extension, qui est le premier à charger une pré-version 4.0 du CLR dans l'application du processus restreint l'ensemble des versions de la CLR peut être utilisé par la suite par ce processus. Si une application gérée avec une boîte de dialogue Ouvrir est construit sur un conflit de version du CLR, puis l'extension, pouvait ne pas fonctionner correctement et peut entraîner des défaillances dans l'application. A l'inverse, si l'extension est le premier à charger dans un processus et un conflit de version de code managé tente de lancer par la suite (peut-être une application gérée ou une application en cours d'exécution des charges de la CLR sur demande), l'opération échoue. Pour l'utilisateur, il semble que certaines fonctionnalités de l'application au hasard d'arrêt de travail, ou de l'application mystérieusement se bloque.

Notez que les versions de la CLR égale ou postérieure à la version 4.0 ne sont généralement pas sensibles au problème de contrôle de version, car ils sont conçus pour coexister les uns avec les autres et avec la plupart des pré-versions 4.0 de la CLR (à l'exception de la version 1.0, qui ne peut coexister avec d'autres versions). Cependant, des problèmes autres que la version des conflits peuvent survenir, comme discuté dans la suite de cette rubrique.

Les Problèmes De Performances

Les problèmes de performances peuvent survenir avec des durées maximales qui imposent de façon significative les performances de la peine, lorsqu'ils sont chargés dans un processus. La performance de la pénalité peut être dans la forme de l'utilisation de la mémoire, l'utilisation du PROCESSEUR, le temps écoulé, ou même l'adresse de la consommation d'espace. Le CLR, JavaScript/ECMAScript, et Java sont connus pour être fort impact runtimes. Depuis que le processus extensions peuvent être chargés dans de nombreux processus, et sont souvent fait à la performance des moments délicats (comme lors de la préparation d'un menu à afficher à l'utilisateur), à fort impact runtimes peut nuire à la réactivité globale.

Un moteur d'exécution qui consomme des ressources importantes peuvent provoquer une défaillance dans le processus d'hôte ou d'une autre dans le processus d'extension. Par exemple, un moteur d'exécution qui consomme des centaines de méga-octets d'espace d'adressage de son segment peut entraîner l'application hôte étant pas en mesure de charger un grand jeu de données. En outre, parce que le processus d'extensions peuvent être chargés dans plusieurs processus, en haut de la consommation des ressources dans une seule extension peut rapidement se multiplier en haut de la consommation des ressources sur l'ensemble du système.

Si un temps d'exécution reste chargé ou sinon continue à consommer de ressources, même lorsque l'extension qui utilise cette exécution a déchargé, alors que l'exécution n'est pas adapté pour une utilisation dans une extension.

Des questions Spécifiques à l' .NET Framework

Les sections suivantes présentent des exemples de problèmes rencontrés avec l'utilisation de code managé pour les extensions. Ils ne sont pas une liste complète de tous les éventuels problèmes que vous pourriez rencontrer. Les questions abordées ici sont les deux raisons qui ont géré le code n'est pas pris en charge dans les extensions et les points à prendre en compte lorsque vous évaluez à l'utilisation d'autres exécutions.

  • Re-entrancy
    Lorsque le CLR bloque un single-threaded apartment (STA) thread, par exemple, en raison d'un Moniteur.Entrez, WaitHandle.WaitOne, ou soutenu instruction lock, le CLR, dans sa configuration standard, entre dans une boucle de message imbriquée pendant qu'il attend. De nombreuses méthodes d'extension sont interdits de traitement des messages, et ce imprévisibles et inattendus réentrance peut entraîner des comportements anormaux qui est difficile à reproduire et à diagnostiquer.

  • Le Multithread Appartement Le CLR crée Runtime Callable des Wrappers pour Modèle d'Objet Composant (COM) des objets. Ces mêmes Runtime Callable Wrappers sont détruits par le CLR du finalizer, qui fait partie de la multithread appartement (MTA). Le déplacement de la procuration de la STA pour le MTA nécessite marshaling, mais pas toutes les interfaces utilisées par les extensions peuvent être muselé.

  • Non-Déterministe De L'Objet De La Durée De Vie
    Le CLR est plus faible durée de vie des objets garantit que le code natif. De nombreuses extensions ont de comptage de référence exigences sur les objets et les interfaces, et le garbage-collection modèle employé par le CLR ne peut pas répondre à ces exigences.

    • Si un objet CLR obtient une référence à un objet COM, le COM de référence de l'objet tenu par le moteur d'Exécution Callable Wrapper n'est pas libéré jusqu'à ce que le moteur d'Exécution Callable Wrapper est le garbage collector. Non déterministe communiqué de comportement peut entrer en conflit avec certains contrats d'interface. Par exemple, le IPersistPropertyBag::Load méthode nécessite aucune référence à la propriété de sac d'être retenu par l'objet lors de la Charge de la méthode retourne.
    • Si un CLR référence d'objet est retourné en code natif, le moteur d'Exécution Callable Wrapper renonce à sa référence à l'objet CLR lorsque le moteur d'Exécution Callable Wrapper appel final à la Libération est faite, mais l'objet CLR est pas terminé jusqu'à ce qu'il est le garbage collector. Non déterministe finalisation peut entrer en conflit avec certains contrats d'interface. Par exemple, la vignette, les gestionnaires sont tenus de libérer toutes les ressources immédiatement lorsque leur référence compteur tombe à zéro.

Utilisations acceptables de Code Managé et d'Autres Runtimes

Il est acceptable d'utiliser du code managé et d'autres environnements d'exécution pour mettre en œuvre out-of-process extensions. Exemples de processus Shell extensions sont les suivantes:

  • Aperçu des gestionnaires d'
  • En ligne de commande basé sur des actions telles que celles enregistrées en vertu de shell\verbe\commande des sous-clés.
  • COM objets mis en œuvre dans un serveur local, pour Shell extension des points qui permettent à l'extérieur de la procédure d'activation.

Certaines extensions peuvent être mis en œuvre soit en cours ou out-of-process extensions. Vous pouvez mettre en œuvre ces extensions comme out-of-process extensions si elles ne répondent pas à ces exigences pour les processus d'extensions. La liste suivante présente des exemples d'extensions qui peuvent être mises en œuvre que ce soit en cours ou out-of-process extensions:

  • IExecuteCommand associé à un DelegateExecute entrée enregistrée sous un shell\verbe\command clé.
  • IDropTarget associés avec le CLSID enregistré sous un shell\verbe\en œuvre droptarget sous-clé.
  • IExplorerCommandState associé à un CommandStateHandler entrée enregistrée sous un shell\verbe sous-clé.

SharpShell

SharpShell le rend facile de créer des Extensions du Shell Windows à l'aide de l' .NET Framework.

Le code source est hébergé sur https://github.com/dwmkerr/sharpshell - vous pouvez poster des questions et demande de fonctionnalité ici ou là. Les Extensions Prises En Charge

Vous pouvez utiliser SharpShell de construire les extensions ci-dessous:

  • Shell Menus Contextuels
  • Gestionnaires D'Icône
  • Info Conseil Des Gestionnaires D'
  • Baisse Des Gestionnaires D'
  • Aperçu Des Gestionnaires D'
  • Icône De Recouvrement Des Gestionnaires D'
  • Miniature Hanlders
  • La Feuille De Propriétés D'Extensions

Les projets qui utilisent SharpShell
1. Trello Menu Contextuel
2. RÉEL Shuffle Lecteur 2.0

Série d'Article sur CodeProject

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X