Quelle est la bonne façon d'implémenter une extension de coquille de propriétés gérée?

StackOverflow https://stackoverflow.com/questions/3200245

Question

Maintenant que .NET CLR 4.0 prend en charge le fonctionnement côte à côte (SXS), il doit maintenant être possible d'écrire une coque Extensions dans le code géré. J'ai tenté cela et a codé avec succès un gestionnaire de propriétés Cela implémente IPropertystelle, iinitializewithstream et ipropertystocapabilités.

le gestionnaire Fonctionne bien et s'appelle comme prévu lors de la navigation de fichiers via l'explorateur. Cela fonctionne aussi bien dans l'affichage de la Propriétés personnalisées dans le panneau de prévisualisation et le panneau «Détail» Propriétés du fichier.

Cependant, quand je tente de Modifiez une propriété dans le panneau de prévisualisation, puis cliquez sur "Enregistrer" Je reçois une erreur "Fichier utilisé" ". Le fichier est ouvert dans l'Explorateur Windows.

Quelques Tidbits:

  1. Lorsque l'explorateur appelle iinitializewithstream.Initialiser la propriété STGM est défini sur stgm_share_deny_write.
  2. et à aucun moment, l'explorateur a appelé ipropertystore.setvalue ou ipropertystore.commit.
  3. Je vois des appels répétés sur mon gestionnaire sur différents threads pour les mêmes propriétés de fichiers.
  4. Alors, que dois-je modifier (ou définir dans le tableau) pour obtenir la propriété enregistrer pour travailler?

    mise à jour:

    Merci à Ben, je l'ai travaillé. La «partie difficile» (au moins pour moi) comprenait que Com Interop n'appellerait jamais ne jetterait ni finaliser sur mon propriété. Cela laissait les fichiers que j'ai traités ouverts jusqu'à ce que le GC a couru.

    Heureusement, le "protocole de gestionnaire de propriétés" fonctionne de telle que lorsque iinitializewithsream.Initialize () est appelé () que la diffalue (), le streammode est réadonnée, et lorsqu'il est appelé pour une streamue (), le StreamMode est readwite et commit () sera appelé à la fin.

    int IInitializeWithStream.Initialize( IStream stream, uint grfMode )
    {
        _stream = stream;
        _streamMode = (Stgm)grfMode;
    
        Load();
    
        // We release here cause if this is a read operation we won't get called back, 
        // and our finializer isn't called. 
        if ( ( _streamMode & Stgm.ReadWrite ) != Stgm.ReadWrite )
        {
            Marshal.ReleaseComObject( _stream );
            _stream = null;
        }
        return HResult.S_OK;
    }
    
    int IPropertyStore.Commit()
    {
        bool result = false;
    
        if ( _stream != null )
        {
            result = WriteStream( _stream );
            Marshal.ReleaseComObject( _stream );
            _stream = null;
        }
    
        return result ? HResult.S_OK : HResult.E_FAIL;
    }
    

Était-ce utile?

La solution

Oui, vous devez addition () le flux pour le garder ouvert et garder la référence correctement.

Notez que l'indexeur utilisera votre gestionnaire de propriétés pour ouvrir également le fichier.Donc, si vous fulgurez l'objet de flux, le fichier restera ouvert.Vous pouvez utiliser le Sysinternals ProceXP pour indiquer quel processus dispose du fichier ouvert ou de procminer pour indiquer quels appels et paramètres utilisés.

Autres conseils

Explorer essaie de s'assurer qu'il n'interfère pas avec d'autres applications pouvant avoir le fichier ouvert.Le fichier pourrait-il être légitimement utilisé par une autre application?Y a-t-il un service de prévisualisation ouvert?

Parfois, nous voyons des gestionnaires de propriétés qui empêchent leurs flux d'ouvertures plus longtemps que nécessaire (ou des gestionnaires basés sur des fichiers qui ouvrent le fichier avec des autorisations restrictives).Pouvez-vous vérifier si vous libérez le ruisseau en temps opportun?

Enfin, je ne pense pas que cela soit lié à votre problème immédiat, mais que l'utilisation des extensions de shell .NET n'est pas supportée.Nous recommandons que cela ne soit pas incorporé à aucun produit.

-ben

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