Der Hintergrund der folgenden Frage ist der, dass ich es unter Windows XP letzlich noch immer nicht geschafft habe, dass ein im Autostart-Ordner eingetragenes Programm genau einmal gestartet wird (und nicht mehrmals). In meinem Fall will ich ein Batchprg. eben genau einmal starten. Ich kann nicht recht verstehen, wieso das (bei mir) so ist, aber - nunja, dann bastelt man eben einen Workaround...
Dieser Workaround sieht bei mir in etwa so aus.
1 Falls Laufwerk Z: definiert ist => Batchfile beenden
2 SUBST Z:
3 ... ; weitere Befehle
Da SUBST sich auf das ganze System auswirkt funktioniert das i.d.R. auch ganz gut.
Es gibt aber einen Schwachpunkt, der in letzter Zeit des öfteren Auftritt.
Befindet sich Aufruf A am Ende der Zeile 1 und Aufruf B ist jetzt am Zug, dringt auch Aufruf B zu Zeile 2 vor, d.h. Aufruf A und B durchlaufen letztlich alle Zeilen. Mein selbstgestrickter Mechanismus funktioniert also nicht immer...
?????
? Weiß jemand eine Möglichkeit wie man das verhindern kann.
Vielen Dank,
Mdl
P.S. Ich finde es eher eine (Batch-)Programmierkniffelei als ein XP-Problem, deshalb lege ich es unter diesem Forum ab...
Programmieren - alles kontrollieren 4.941 Themen, 20.708 Beiträge
also ein batchfile wird mehrfach aufgerufen im autostart ordner?
der rest überfordert mich zum teil etwas
> dringt auch Aufruf B zu Zeile 2 vor
äähm .. ja.
tipp nebenher: statt subst ginge ja auch set -> environment variable
wie oft genau wird dein batchfile denn ausgeführt nach dem start ?
> also ein batchfile wird mehrfach aufgerufen im autostart ordner?
Ja. Ein Batchfile, das sich im Autostart-Ordner befindet wird statt genau einmal eben mehrfach PARALLEL ausgeführt. (Im folgenden Kontext eben mit Aufruf A und B bezeichnet).
> tipp nebenher: statt subst ginge ja auch set -> environment variable
leider nein. Wird eine Environment-Variable in einer DOS-Box gesetzt wirkt sich dies nicht auf die andere DOS-Box aus...
> wie oft genau wird dein batchfile denn ausgeführt nach dem start ?
Seltsamerweise dreimal...
Gruß,
Mdl
> Seltsamerweise dreimal...
Nein, doch 'nur' zweimal.
Ich starte zeitgleich noch ein Batchfile, deshalb waren kurzzeitig drei entsprechende Fenster offen.
Gruß,
Mdl
Für diesen Anwendungsfall wäre wohl einer der run_once Zweige in der Registry besser geeignet...
Gruß
Borlander
Probiere mal, deine Batchdatei als CMD-datei zu erstellen.
Die wird garantiert nur beim Starten einmal ausgeführt.
Also nicht xxxxx.bat, sondern xxxxx.cmd
Habe für mein Ursprungsproblem (doppeltes Ausführen eines Autostart-Eintrags) eine bereits früher gefundene Lösung wiederentdeckt:
Autostart-Ordner nur noch einmal ausführen
Registry-Änderungen:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Startup: Textersetzung 'All Users' -> '' (z.B. ICH)
innerhalb des Eintrags
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Startup: Textersetzung '%ALLUSERSPROFILE%' -> '%USERPROFILE%' innerhalb des Eintrags
Bem: Obwohl der Autostart-Ordner ja in 'C:\Dokumente und Einstellungen\All Users\Startmenü\Programme\Autostart' gelegt wurde, wird er jetzt trotzdem (genau einmal) ausgeführt...
ABER ...
Trotzdem würde mich eine allgemeine Lösung für das Problem interessieren, wie man in einem Batchfile Bereiche definieren könnte, die bei parallel ablaufenden Batchfiles nur jeweils von einem gleiczeitig abgearbeitet werden können (ein evtl. anderer Anwärter müsste dann solange warten, bis das diesen Bereich innehabende Batchfile den Bereich verlassen hat.
Mir fallen da Stichworte wie 'Mutual Exclusion' und 'Semaphore' ein...
Irgendeine Idee?
Viele Grüße,
Mdl
Ich hab immer wieder mal gesagt das kann man mit Batchfiles nicht machen und dann kam
einer und hats doch hingekriegt aber jetzt trau ich mich nochmal.
Das kann man mit Batchfiles nicht machen.
Da wäre vielleicht ein anderes Skript System für dich interessant.
Mit reinen Batch-Kommandos wahrscheinlich wirklich nicht, aber da innerhalb Batchfiles ja auch EXE-Dateien aufgerufen werden können, vielleicht doch...
Gibt es z.B. die Möglichkeit, dass ein EXE-File nur in einer Instanz läuft, egal wie oft es aufgerufen wird? Oder besser: Dass sich die verschiedenen Instanzen Und dass die verschiedenen Instanzen EINE globale Variable, einen Zeiger teilen?
Dann könnte man das Problem ja z.B. auf C verlagern, wo es ja sicher eine Lösung gibt...
????
? Frage also konkret mal: Wie können sich in C verschiedene Instanzen eines EXE-Files bestimmte Variablen teilen?
Grüße,
Mdl
also der autor eines programms entscheidet ob er es so anlegen möchte das seine exe
systemweit nur einmal gestartet werden kann dazu gibt es verschiedene mechanismen.
ein program nachträglich dazu zu bringen geht nur wenn du eine eigene exe
schreibst die prüft ob ein programm dieses namens/pfad schon läuft
und es dann wahlweise startet.
in c/c++ unter windows gibts eine reihe möglichkeiten das sich mehrere instanzen
einer exe oder auch unterschiedliche programme speicherbereiche
also variablen zu teilen. das sinnvollste ist der sogenannte gemeinsam genutze speicher.
ist relativ simpel wenn man wirklich nur ein paar primitive variablen sharen will.
eine dll unter windows kanns mit vc++ noch einfacher haben, dazu reichen ein paar #pragma
anweisungen vor und nach der variablen deklaration.
> das sinnvollste ist der sogenannte gemeinsam genutze speicher.
ist relativ simpel wenn man wirklich nur ein paar primitive variablen sharen will.
????????
? Ok. Wie geht das in C/C++?
Wie muss ich z.B. folgenden Code erweitern, dass die globale Variable MySharedVal vom Typ 'Zeiger auf struct MySharedStruct' (MySharedStruct könnte eine beliebig definierte Struktur im Header-File sein) für alle Instanzen (Aufrufe) der Applikation geteilt wird.
extern struct MySharedStruct *MySharedVal; // UNVOLLSTÄNDIG...
Ideal wäre natürlich wenn es unter C/C++ ein Schlüsselwort gäbe, mit dem dies bewerkstelligt werden könnte.
Der Code wäre dann vermutlich am Programmanfang irgendwie so aus:
if(MySharedVal==NULL)
MySharedVal=new MySharedStruct;
Neben der Tatsache, dass die Adresse von MySharedVal in allen Instanzen des erzeugten EXE-Files dieselbe ist (oder zumindest deren Wert, d.h. der Zeiger), dürfte (und sollte) der von der ersten Instanz angeforderte Speicher erst wieder freigegeben werden, wenn die letzte Instanz des EXE-Files beendet wird.
Vielen Dank,
Mdl
Sorry per Schlüsselwort in C++ geht das leider nicht.
Das Betriebssystemspezifisch, das kannst du nicht mal mehr ohne weiteres portieren.
Vielleicht hilft dir das hier:
http://cplus.kompf.de/artikel/memmap.html
http://www.codeguru.com/cpp/w-p/win32/tutorials/article.php/c9823/
http://www.codeguru.com/cpp/w-p/win32/tutorials/article.php/c9825__1/
Google Search: "C++ Windows CreateFileMapping"
> Sorry per Schlüsselwort in C++ geht das leider nicht.
Schade, schade...
Aber war ja auch nicht eigentlich zu erwarten...
Ok, werde mich dann mal diese oder nächste Woche etwas rumschlagen mit der Materie...
Neben dem gemeinsamen Speicher interessiert mich besonders, wie es realisiert wird, dass bei jedem Zugriff darauf parallel ablaufende Prozesse, die auf diesen Speicher auch Zugriff haben nicht gleichzeitig darauf zugreifen können...
Vielen Dank für die Links!!!
Grüße,
Mdl
Hallo!
Also, Batchfiles sind ja nun wirklich seeehr geeignet für
Interprozesskommunikation.
Ich könnte Dir zwar einige Lösungsansätze nennen, aber lesen bildet:
http://de.wikipedia.org/wiki/Semaphor_(Informatik)
Gruss
ChrE
wie wäre es wenn du es machst wie die Kollisionserkennung beim LAN?
Beim start der Batchdatei startest du ein Programm das eine zufällige anzahl millisekunden(sollte dann schon grösser 2k sein) wartet. danach wird überprüft, ob dein LW Z bereits existiert. Da es unwahrscheinlich ist, dass 2x die gleiche zufallszahl ermittelt wird, wird das eine script vor dem anderen ausgeführt, und das andere wird dann feststellen, dass es das 2. ist. LW Z kannste ja nach ausführen des scripts mit subst /D wieder Löschen und für das warteprogramm sollten 5 zeilen C-Code mehr als genug sein.
Wäre es nicht einfacher die Ursachen zu suchen, statt mit großem Aufwand an den Symptomen herumzudoktern? ;-)