Hallo!
Ich habe folgendes Problem:
Ich habe mir einen Eintrag im Explorer Context Menü gemacht und möchte damit eine beliebige Anzahl von Files beim starten an mein Programm übergeben. Das funktioniert auch wunderbar bei einem File nur bei mehreren startet er das Programm jedesmal in einer neuen Instanz und übergibt den nächsten Dateinamen.
Die Frage ist nun, wie ich es schaffe, dass er alle Dateinamen in die erste Instanz des Programmes übergibt.
Ich habe bereits eine Prozessabfrage eingebaut die überprüft ob bereits mehr als eine Instanz läuft und wenn ja das Programm sofort wieder beendet. So habe ich zumindest erreicht dass nur eine Instanz laufen kann. Nun ist die Frage ob das schon mal in die richtige Richtung geht oder nicht 🙂.
Ich habe gehört, dass es evtl. mit Windows API (genauer WindowMessages) gehen könnte, nur muss ich bei API passen. Damit habe ich mich noch nicht beschäftigt. Außerdem kommt es mir etwas komisch vor, das bei sagen wir 1000 Files das Programm auch 1000x gestartet werden muss um den Parameter zu übergeben und sich danach wieder zu beenden.
Wahrscheinlich bin ich total auf dem Holzweg 😉.
Plz help.
Irgendwie konnte mir scheinbar niemand helfen, deswegen versuche ich mein Problem nochmal etwas genauer zu schildern.
Ich möchte mein Programm aus dem Windows Explorer heraus starten indem man mehrere Dateien markiert und per Rechtsklick einen von mir in der Registry hinterlegten Eintrag anklickt (Context Menü). In der Registry habe ich als Programmparameter %1 eingetragen.
Wie ich bei Tests festgestellt habe started Windows jedoch das Programm für jedes markierte File extra und übergibt jeweils das nächste File.
Meine Frage ist wie ich es erreiche, dass eben alle Files an die erste (und einzige) Instanz meines Programmes abgegeben werden.
Ich weiß nicht ob das ohne Windows API überhaupt möglich ist, bisher habe ich es so gelöst, das ich einfach nur Verzeichnisse erlaube. Natürlich ist das blöd wenn man eben nur bestimmte Dateien in einem Verzeichnis braucht.
Ich hoffe ich habe mich jetzt etwas klarer ausgedrückt 😉.
Hmm ich versuche es mal 😁
Du kannst doch über die Process Klasse deine EXE starten. Jetzt könntest du als Argumente die ganzen Dateinamen übergeben du die auswerten möchtest.
In der Main() Methode des Programmes kannst du jetzt die Dateinamen auswerten:
public static void Main( string[] args )
{
if ( args.length > 0 )
{
for each ( string s in args )
{
// hier jetzt über die Variable s auf die einzelnen Werte zugreifen
}
}
}
Ich hoffe ich habe deine Frage richtig verstanden.
Mit freundlichen Grüßen
René Paschold
.NET Developer / Trainer / Speaker / Author /
Projectleader / Software-Architect
.blog http://www.rene-paschold.de/
.business http://www.smarthouse.de/
Danke für das Engagement!
Ich bin nicht sicher ob du's richtig verstanden hast. Ich nehm mal als Beispiel den Winamp 🙂. Wenn man mehrere Musicfiles markiert und öffnet startet sich der Winamp und übernimmt alle markierten Files in die Playlist. Sowas brauche ich auch. Den Eintrag im Context Menü hab ich ja bereits, abgesehen davon, dass ich nicht sicher bin ob der Aufruf mit "Programm.exe %1" richtig ist.
Wie meintest du das, mit der Process Klasse Argumente übergeben? Ich hab mit dieser Klasse noch nichts gemacht außer nach Prozessen gesucht.
Hallo feigling,
das mit dem %1 ist schon ok.
Ansonsten würde ich wirklich vermuten, dass das eingetragene Programm für jede einzelne Datei aufgerufen wird. Wenn du willst, dass alle Paramter bei einer Instanz ankommen, wie das bei Winamp ja auch ist, musst du deine Anwendung so programmieren, dass die neu gestarteten Instanzen gucken, ob schon eine Instanz läuft, und die Parameter dann an diese übermitteln. Wie so ein Programm aussehen könnte steht in Dateiassoziation
herbivore
Ok falsch verstanden 😁
@herbivore
Da hast aber ein nettes Beipspiel gecodet 😁
Mit freundlichen Grüßen
René Paschold
.NET Developer / Trainer / Speaker / Author /
Projectleader / Software-Architect
.blog http://www.rene-paschold.de/
.business http://www.smarthouse.de/
Da war ich ja garnicht sooo falsch unterwegs. Ich hatte schon code der prüft ob das Programm schon läuft und es evtl. beendet. Allerdings hab ich das eben mit der Process Klasse realisiert.
Ich werd mir deine Links das mal genauer anschauen.
Vielen Dank.
Hallo mal wieder!
Also ich habe es inzwischen mit Remoting hinbekommen allerdings ist das eine sehr langsame Methode.
Gesetz dem Fall man möchte sagen wir mal 500 Files hinzufügen dauert das schon ne Weile.
Ich frage mich ernsthaft wie das andere Programme machen.
Es wäre super wenn jemand noch andere Ideen hat.
Bye
Hallo
Andere Programme machen das via DDE. Imho wird das auch direkt von Windows unterstützt (siehe Extras->OrdnerOptionen->Dateitypen im Explorer). Da DDE allerdings nicht mehr unterstützt wird unter .NET (und logischerweise auch nicht unter anderen Betriebssystemen wie Linux) musst du die WinAPI funktionen direkt aufrufen. Siehe z.B. DDEInitialize in der MSDN
Hallo mal wieder!
Ich habe weiter geforscht nach einer schnellen Möglichkeit viele markierte Dateien über Kontext-Menü in mein Programm zu bekommen und habe in der Registry etwas gefunden.
Nachdem ich bisher davon ausging, dass der Winamp diese Aufgabe auch so ähnlich löst wie ich, habe ich nun rausgefunden, dass das offensichtlich nur eine veraltete Methode war die aus kompatibilitätsgründen noch vorhanden ist.
Kurz erklärt: Um ein Programm über das Explorer Kontext-Menü zu starten muss man einen Registry Schlüssel anlegen. Das Ganze geschiet unter HKCR unter der jeweiligen Dateiendung. Der Schlüssel lautet dann "Programm.exe" "%1" wobei %1 eben dann ein Dateiname ist der mit übergeben wird. Hat man mehrere Dateien markiert ruft er immer neue Instanzen mit neuen Parametern auf und man muss diese von den neuen Instanzen an die erste übergeben. Das habe ich bisher mit Remoting gelöst.
Winamp scheint das auf aktuellen Systemen anders zu lösen. Es gibt für Winamp Files einen Schlüssel "DropTarget" in dem wiederum eine Class ID steht (CLSID). Diese wird an einer anderen Stelle in der Registry sozusagen mit der Executable verknüpft.
Wenn man nun das Programm aus dem Kontext started wird kein Dateiname mehr übergeben sondern Windows startet das Programm mit dem Parameter "-embedded".
Das DropTarget lässt auf das IDropTarget Interface schließen, was bedeuten würde dass es was mit Drag&Drop zu tun hat.
Ich vermute dass es auch so geht und dass Windows die Files irgendwie bereitstellt man sich das im Programm dann "abholen" muss.
Außerdem vermute ich dass es etwas mit COM zu tun hat, womit ich mich leider überhaupt nicht auskenne. MSDN nennt als Option für solche Operationen neben DDE eben "COM und IDropTarget" wobei letzteres nur unter XP gehen soll und erheblich schneller sein soll.
Hat irgendjemand ne Idee? Ich such seit drei Tagen rum und kann nichts finden.
Bump...
Ich hab mich mal wieder an das Problem gesetzt und bin immer noch am verzweifeln.
Vielleicht gibt's ja mittlerweile jemanden der mir helfen kann?
Cheers,
feigling
das ist haargenau das was ich auch suche 😁
da ich wahrscheinlich noch weniger von c# verstehe als feigling komm ich hierbei auch nicht weiter.
wär klasse wenn sich jemand hier mit dieser thematik auskennt und etwas dazu erzählen würde 👍
Hallo zusammen,
in Creating a File Association - Verbs and File Associations im Abschnitt "How the Shell Invokes Verbs" steht zu lesen:
There are three ways that the Shell can invoke a verb.
* As a command line call, as specified in a command key. * Through Dynamic Data Exchange (DDE), by using a ddeexec key. * Through COM and IDropTarget, by using a DropTarget key.
Das heißt für mich, dass DropTarget mit DDE schon mal nichts zu tun hat. Wenn man den Links in dem Artikel folgt, sollte man alle nötigen Informationen zusammen bekommen.
herbivore
Leider nicht. Das habe ich auch schon mal versucht. Alles was ich rausgefunden habe war, dass Windows das Executable über das IDropTarget Interface anspricht. Mehr Informationen gab es da leider nicht.
Da ich jedoch gerade mit einem Projekt beschäftigt war, hatte ich weder Zeit weiter zu suchen (frag doch mal beim WinAMP-Team nach), noch einen IDropTarget-Logger zu schreiben.
Vielleicht komme ich in Kürze doch noch dazu (ineressiert mich nämlich selbst), dann würde ich meine Erkenntnisse hier posten.
Hallo Leute, ich bin noch ein wenig unerfahren was Registry bearbeiten betrifft. Habe mir diesen Thread schon genauerstens angeschaut und bin jetzt in der Lage beim Aufruf meines Programmes gleich den Namen der Datei mit %1 an mein Programm zu übergeben und in ein ListView Control zu schreiben. Allerdings klappt das nicht, wenn ich mehrere Dateien auswähle. So wie das hier im Forum beschrieben wird ist das für mich sehr schwierig zu realisieren. Gibt es vielleicht eine einfachere Möglichkeit. Danke im Voraus
Hallo Kr@uti,
meinst nicht, dass wir einfachere Möglichkeiten beschrieben hätten, wenn wir sie kennen würden? Oder meinst du, wir schreiben extra schwere Lösungen, damit die Anfänger was zu knabbern haben?
herbivore
Hallo herbivore, also so habe ich das nicht gemeint. Natürlich ist mir klar das dieses Forum jeden helfen will zumal es kostenlos ist und nicht absichtlich schwierige Lösungen reinstellt wenn es einfachere gibt. Dadurch das dieser Thread allerdings schon etwas älter ist dachte ich gestern das es irgendwo vielleicht schon eine neuere bzw. bessere Lösung gibt, und das war auch der Grund warum ich gefragt habe. Dennoch danke für Deine Antwort.
Hallo Kr@uti,
Dadurch das dieser Thread allerdings schon etwas älter ist dachte ich gestern das es irgendwo vielleicht schon eine neuere bzw. bessere Lösung gibt, und das war auch der Grund warum ich gefragt habe.
naja als "alt" würde ich diesen thread nicht bezeichnen.
es gibt hier im forum bestimmt "viel ältere" threads in denen lösungen stehen, die immer noch ihre daseinsberechtigung besitzen bzw. es keine "neuere/schönere/bessere/kürzere/..." Lösung gibt!
nils
Wenn ich als Parameter %1 übergebe, habe ich das Problem, dass wenn ich mehrere Dateien markiert habe gar nichts passiert. Funktioniert nur bei Einzelnen Dateien. Habe dann Verknüpfung auf irgendein Exe File gelegt u dort ist das gleiche Probleme. Also sollte nichts mit meinem Code zu tun haben....weißt jemand Rat? Danke
P.S Mein Programm ist ein Archivierungstool für Files...das heißt, dass Dateiendungsunabhängig sein soll
Hallo ZeroQool,
Windows ruft das Programm für jede Datei einzeln und immer wieder neu auf.
herbivore
Habe es nun ganz einfach gelöst...
Eine Verknüpfung unter: C:\Dokumente und Einstellungen\Administrator\SendTo
ohne Parameter ect.
nun kann man ein File oder mehrere Files markieren u über die Verknüpfen SENDEN AN das Programm aufrufen. Das Programm wird auch nur einmal aufgerufen...es ist deshalb keine Instanzabfrage mehr nötig