myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » Projekte » KShellExtensions: Managed Shell Extensions
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

KShellExtensions: Managed Shell Extensions

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Khalid Khalid ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2534.gif


Dabei seit: 19.07.2005
Beiträge: 3.505
Entwicklungsumgebung: Visual Studio 15/17
Herkunft: Hannover


Khalid ist offline

KShellExtensions: Managed Shell Extensions

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

da die CLR 4 nun Side-By-Side Prozesse unterstützt ( CLR Inside Out: In-Process Side-By-Side*) ist es von Microsoft nun gestattet Shell Extensions in managed Sprachen zu schreiben.

Aus dem Grund habe ich angefangen ein Framework zu schreiben, mit dem man sehr einfach (hoffe ich jedenfalls) eigene Shell Extensions schreiben kann. Dieses Framework setzt vollständig auf .NET 4.0 auf.

Momentan unterstützt die Bibliothek folgende Shell Extensions:
  • Shell Icon Overlayer
Folgende Extensions sind geplant:
  • Shell Thumbnail Preview
  • Shell Contextmenu Extensions
  • Copy Hooks
----------------------------------------------------------------------------------------------

Kleine FAQ zu den Shell Extensions:

Wie registriere ich die DLLs, damit der Explorer diese auch findet?
Da Shell Extensions COM Objekte sind, müssen diese per RegAsm registriert werden. RegAsm wird mit dem .NET 4.0 mitgeliefert und befindet sich im Frameworkordner.

Die DLL ist registriert, aber der Explorer reagiert nicht!?
Das liegt daran, das die DLLs nicht im GAC liegen. Die KShellExtension.dll, sowie die DLL die die Shell Extension enthält müssen im GAC liegen. Diese können per GacUtil in den GAC gelegt werden.

Der Explorer reagiert unter x64 immer noch nicht auf die DLLs!?
Bei x64 Systemen muss darauf geachtet werden, das das Tool RegAsm auch in der x64 Variante benutzt wird. Sonst wird die DLL als WOW6432 registriert und der Explorer hostet nur x64 DLLs unter x64.

Kann ich die Einstellung AnyCPU verwenden?
Ja, das ist kein Problem. Bei x64 Systemen muss nur daruf geachtet werden, das auch die x64 Variante von RegAsm benutzt wird.

Alles ist richtig installiert, aber der Explorer reagiert immer noch nicht!?
Beim Registrieren wird zwar per SHChangeNotify der Shell mitgeteilt, das sich was getan hat, aber meist reagiert der Explorer erst, wenn dieser neu gestartet wird. Also entweder das System neu starten, oder per Task Manager den Explorer abschießen und neu ausführen.

----------------------------------------------------------------------------------------------

Achtung:
Theoretisch wäre es möglich die Solution auch für .NET 3.5 zu kompilieren. Ich rate davon ab! Das kann zu fatalen Systemabstürzen führen, soweit das die Maschine nicht mehr hochfahren kann!

*

Zitat:
With the ability to have multiple runtimes in process with any other runtime, we can now offer general support for writing managed shell extensions—even those that run in-process with arbitrary applications on the machine. We still do not support writing shell extensions using any version earlier than .NET Framework 4 because those versions of the runtime do not load in-process with one another and will cause failures in many cases.


Dateianhang:
unknown KShellExtension.zip (7 KB, 343 mal heruntergeladen)
07.04.2010 11:21 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Khalid Khalid ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2534.gif


Dabei seit: 19.07.2005
Beiträge: 3.505
Entwicklungsumgebung: Visual Studio 15/17
Herkunft: Hannover

Themenstarter Thema begonnen von Khalid

Khalid ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

So, gleich mal das erste Beispiel: Ein Shell Icon Overlayer

Um ein Shell Icon Overlayer zu erstellen, muss eine neue Klassenbibliothek erstellt werden und gleich ein Verweis auf die KShellExtensions hinzugefügt werden.

Die Extension muss dann von der Klasse "ShellIconOverlayIdentifier" abgeleitet werden und die abstrakten Methoden müssen dann mit Leben gefüllt werden.

C#-Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KShellExtension;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Diagnostics;

namespace Sample1.IconOverlay
{
  [ComVisible(true)]
  [Guid("[Eindeutige GUID]")] //kann z.B. auf http://www.guidgen.com/ generiert werden
  public class Sample1IconOverlay : ShellIconOverlayIdentifier
  {
    [ComRegisterFunction()]
    public static void RegisterServer(Type type)
    {
      ShellComRegister.RegisterShellIconOverlayIdentifier(typeof(Sample1IconOverlay));
    }

    [ComUnregisterFunction()]
    public static void UnregisterServer(Type type)
    {
      ShellComRegister.UnregisterShellIconOverlayIdentifier(typeof(Sample1IconOverlay));
    }

    public override bool IsOverlayIconVisible(string fileName, int attributes)
    {
      return fileName.ToLower().EndsWith(".exe");
    }

    public override string GetOverlayIconLocation()
    {
      // ToDo: Der Pfad muss vollständig angegeben werden. Die beiliegende Icon-Datei
      // muss also an einem festen Ort kopiert werden, und dann muss hier ebenfalls der
      // Pfad angepasst werden.
      return @"d:\star_blue.ico";
    }

    public override ShellIconOverlaySource GetOverlayIconSource()
    {
      return ShellIconOverlaySource.FromFile;
    }

    public override int GetOverlayIconIndex()
    {
      return 0;
    }
  }
}

Zum Code:
Wichtig ist, das die Klasse ComVisible ist und eine eindeutige ID anhand einer GUID erhält. Um beim Registrieren der DLL gleich alle nötigen Registryeinträge zu schreiben, müssen zwei statische Methoden hinzugefügt werden, die mit den Attributen ComRegisterFunction und ComUnregisterFunction versehen werden. In der RegisterFunction werden dann über die Hilfsklasse "ShellComRegister" alle nötigen Registryeinträge geschrieben. Und in der UnregisterFunction werden diese Einträge wieder entfernt.

Mit der Methode "IsOverlayIconVisible" wird bestimmt, bei welcher Datei das Icon angezeigt werden soll. "fileName" ist dabei der vollqualifizierte Dateiname. In dem obigen Beispiel soll also das Icon nur angezeigt werden, wenn diese mit ".exe" endet.

Die Methode "GetOverlayIconLocation" gibt an, wo sich die Datei befindet, in der das Icon abgelegt ist. Das können direkt ICO Dateien sein, aber auch DLL und EXE Dateien. Der Pfad muss dabei vollständig angegeben werden.

Mit "GetOverlayIconSource" gibt man an, ob es sich bei der Quelle direkt um eine ICO Datei handelt ("FromFile"), oder um eine Auflistung von Icons ("FromIndex"). Wird als Quelle eine EXE oder DLL angegeben, oder es sich um eine ICO Datei mit mehreren Icons handelt, muss FromIndex angegeben werden.

Um den Index festzulegen muss in der Methode "GetOverlayIconIndex" der Index angegeben werden, beginnend bei 0. Bei "FromFile" ist dies immer 0.

Um die fertige DLL zu registrieren müssen dann in der Console (als Administrator) folgende Befehle ausgeführt werden

Code:
1:
2:
3:
gacutil /f /i KShellExtension.dll
gacutil /f /i Sample1.IconOverlay.dll
regasm Sample1.IconOverlay.dll

Danach den Explorer neu starten und kontrollieren, ob der Explorer die Extension erkannt hat.

Im Anhang befindet sich das Beispielprojekt.


Dateianhang:
unknown Sample1.zip (216,38 KB, 272 mal heruntergeladen)

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Khalid am 08.04.2010 14:17.

07.04.2010 11:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Khalid Khalid ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2534.gif


Dabei seit: 19.07.2005
Beiträge: 3.505
Entwicklungsumgebung: Visual Studio 15/17
Herkunft: Hannover

Themenstarter Thema begonnen von Khalid

Khalid ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hier noch ein Screenshot, auf dem man sieht, das die Extension erfolgreich geladen wurde. Jede "exe" Datei wird jetzt mit einem blauen Stern "überdeckt"

Khalid hat dieses Bild (verkleinerte Version) angehängt:
Unbenannt.png
Volle Bildgröße

07.04.2010 11:23 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
edsplash edsplash ist männlich
myCSharp.de-Mitglied

avatar-3111.jpg


Dabei seit: 19.04.2008
Beiträge: 390
Entwicklungsumgebung: VS2010


edsplash ist offline Füge edsplash Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Khalid

Wäre es mit den Managed Shell Extensions nun theoretisch möglich auf das Drop Event des Explorers zu reagieren? Da gibt es ja viele sehr komplizierte und nur knapp funktionierende (wie z.b.  hier besprochen) Lösungsansätze.

Gruss
07.04.2010 20:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
winSharp93 winSharp93 ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2918.png


Dabei seit: 19.01.2007
Beiträge: 5.742
Herkunft: Stuttgart


winSharp93 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Klingt interessant - werde ich mir mal im Laufe der nächsten tage anschauen.

Nur ein Verbesserungsvorschlag:
Ersetzte folgende Zeile im Beispiel:

C#-Code:
[Guid("B8FA9E43-38E6-4654-8A13-FF905AD22CE6")]

durch

C#-Code:
[Guid("[Eindeutige GUID]")] //kann z.B. auf http://www.guidgen.com/ generiert werden

um ein paar schwer lokalisierbare Probleme, die aufgrund eifriger Copy&Paster auftreten könnten, von vornehinein auszuschließen Augenzwinkern
07.04.2010 21:14 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Khalid Khalid ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2534.gif


Dabei seit: 19.07.2005
Beiträge: 3.505
Entwicklungsumgebung: Visual Studio 15/17
Herkunft: Hannover

Themenstarter Thema begonnen von Khalid

Khalid ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@edsplash:
In dem verlinkten Artikel gibt es wiederum ein Link zu Codeproject für die Implementation eines IStream. Genau das ist eigentlich der richtige Weg. Nur benutzt der Autor die .NET Klassen. Man muss aber voll auf Win32 gehen. Das wird ein schönen Stück komplizierte Arbeit :)

Willst du denn genau das gleiche erreichen? Also auch ein physich nicht vorhanden Bytestream in den Explorer kopieren?


@winSharp93:
Danke, habe ich im Beitrag geändert.
08.04.2010 15:05 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
edsplash edsplash ist männlich
myCSharp.de-Mitglied

avatar-3111.jpg


Dabei seit: 19.04.2008
Beiträge: 390
Entwicklungsumgebung: VS2010


edsplash ist offline Füge edsplash Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Khalid:
Willst du denn genau das gleiche erreichen? Also auch ein physich nicht vorhanden Bytestream in den Explorer kopieren?

Ja Prinzipiell.

Gäbe ja noch die Möglichkeit ein eindeutiges, temporäres File zu übergeben und sich mit einem File System Watcher den Pfad zu holen, wo die Datei hinverschoben wird.

Ich glaube aber gelesen zu haben, dass dieses Problem auch über Shell Extensions zu lösen wäre und darum habe ich gefragt. ;)

Gruss
08.04.2010 19:59 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Khalid Khalid ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2534.gif


Dabei seit: 19.07.2005
Beiträge: 3.505
Entwicklungsumgebung: Visual Studio 15/17
Herkunft: Hannover

Themenstarter Thema begonnen von Khalid

Khalid ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi

Es gibt auf CodePlex ein Projekt ( LizardTF: allerdings in C++), welches eine Shell Extension für den TFS bereit stellt. Die Dateien liegen in dem Moment ja auch nicht physisch auf der Platte, sondern im Server. Mit dieser Shell Extension kann man diese Dateien aber auch einfach irgendwo hinziehen. Deswegen gehe ich mal davon aus, das es mit einer Shell Extension machbar ist. Man müsste sich mal den Sourcecode anschauen, aber C++ sieht immer so zugemüllt aus :)
09.04.2010 08:13 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JAck30lena JAck30lena ist männlich
myCSharp.de-Team

avatar-2653.jpg


Dabei seit: 01.10.2006
Beiträge: 11.397
Entwicklungsumgebung: Visual Studio 05/08/10 Prof.


JAck30lena ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von winSharp93:
C#-Code:
[Guid("[Eindeutige GUID]")] //kann z.B. auf http://www.guidgen.com/ generiert werden

um ein paar schwer lokalisierbare Probleme, die aufgrund eifriger Copy&Paster auftreten könnten, von vornehinein auszuschließen ;)

kann man auch direkt in VS -> Tools -> Create GUID -> 4. Registry Format -> Copy
und dann nur noch an der passenden stelle im code einfügen.
09.04.2010 09:17 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 9 Jahre.
Der letzte Beitrag ist älter als 9 Jahre.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 14.12.2019 22:22