Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
triti
Anmeldungsdatum: 23.04.2009 Beiträge: 44
|
Verfasst am: 26.07.2009, 12:23 Titel: Betriebssystembefehl funktioniert unter QB nicht |
|
|
Hallo!
Betriebssystem Windows XP
Ich mache jeden Tag eine eine automatische Sicherung von einem Verzeichnis mit sehr vielen Dateien. Mit QBasic4.5, shell und xcopy. Das funktioniert 1A.
Die Kopie von dem Verzeichnis wird dann aufs aktuelle Datum umbenannt. Wenn mehr als 10 Kopien vorhanden sind, soll die älteste gelöscht werden.
Wenn ich jetzt eingebe:
shell "rd /q/s c:\sicher.ung\20072009" funktioniert das nicht.
Meldung "/q unzulässige Option, auch /s.
Unter Windows/Start/ausführen gehts auch nicht.
Gebe ich dort aber cmd ein und dann den befehl direkt im DOS Fenster, gehts.
Im TurboNavigator gibt es auch ein Fenster, wo man einen Betriebssystembefehl eingeben kann, dort gehts.
Warum? Und wie kann man... ?
Weiss das jemand?
lg
Triti |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 26.07.2009, 12:45 Titel: |
|
|
Hallo,
RD ist keine eigenständige Anwendung, die irgendwo in %PATH% läge und somit per "Ausführen" erreichbar wäre. Dabei handelt es sich meines Wissens um eine Funktion von CMD, die außerhalb von CMD nicht aufrufbar ist. Um von QB aus oder über "Ausführen" RD in der gewohnetn Form benutzen zu können (das RD von QB/COMMAND ist anders als das aus CMD!*), muss zunächst CMD gestartet und dann RD darin zur Ausführung gebracht werden. Das kann man wie folgt machen:
Code: | 'Beispielcode: Aus QB heraus Befehle in CMD.EXE ausführen
'Getestet unter Windows XP SP3 - Sebastian, 26.07.2009
DECLARE FUNCTION CmdPath$ ()
CLS
Cmd$ = CmdPath$
PRINT "Hier liegt CMD: ";
COLOR 14
PRINT Cmd$
COLOR 7
PRINT
PRINT "Starte jetzt ";
COLOR 14
PRINT "RD";
COLOR 7
PRINT " mit Parameter ";
COLOR 14
PRINT "/?";
COLOR 7
PRINT " ..."
PRINT : PRINT
SHELL Cmd$ + " /C RD /?"
SLEEP: END
'Funktion kann weggelassen werden, wenn man sich auf eine korrekte PATH Einstellung verlassen kann
FUNCTION CmdPath$
'Die Umgebungsvariable COMSPEC enth„lt, wenn aus QB heraus darauf
'zugegriffen wird, den Pfad zu COMMAND.COM.
'Innerhalb der Windows-Eingabeaufforderung CMD ist darin der Pfad zu
'CMD.EXE abgelegt.
C$ = ENVIRON$("COMSPEC")
IF C$ = "" THEN
CLS
PRINT "Fehler, die Umgebungsvariable COMSPEC konnte nicht gelesen werden."
PRINT "Sie verwenden m”glicherweise eine ungeeignete OS-Version."
SLEEP: END
END IF
'Letztes Vorkommen des Backslash finden
bslash% = 0
FOR i% = 1 TO LEN(C$)
Zeichen$ = MID$(C$, i%, 1)
IF Zeichen$ = "\" THEN bslash% = i%
NEXT i%
IF bslash% = 0 THEN
CLS
PRINT "Fehler, COMSPEC enth„lt keine vollst„ndige Pfadinformation!"
SLEEP: END
END IF
'Pfad vom Dateinamen trennen...
NurPfad$ = LEFT$(C$, bslash%)
'...und neuen Dateinamen zusammensetzen, dann zurckgeben:
CmdPath$ = NurPfad$ + "CMD.EXE"
'CMD.EXE liegt n„mlich in dem Verzeichnis, in dem auch COMMAND.COM liegt.
'(Meistens C:\WINDOWS\SYSTEM32)
END FUNCTION |
* Anmerkung: Um dies festzustellen, genügt es, einmal die Ausgabe von SHELL "RD /?" in QB mit der Ausgabe von RD /? innerhalb von CMD zu vergleichen.
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
triti
Anmeldungsdatum: 23.04.2009 Beiträge: 44
|
Verfasst am: 26.07.2009, 19:21 Titel: |
|
|
Spitze! Vielen Dank Sebastian, ich werde das morgen auf dem Rechner auf dem das Programm laufen soll, ausprobieren.
lg
Triti |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 26.07.2009, 20:07 Titel: |
|
|
Von eigenen Projekten weiss ich nur: Auch XP und selbst Vista sowie Windows 7 besitzen neben CMD.EXE auch immer noch COMMAND.COM (kein Witz - probiert es auch: "Start"->"Zubehör"->"Eingabeaufforderung" und dann "command") als DOS-Kompatibilitätsrelikt für die NTVDM. Lösung, um von der vollen CMD.EXE-Leistung zu profitieren:
Code: | SHELL "cmd /c befehl /argumente" |
z.B.
Code: | SHELL "cmd /c rmdir /s foobar" |
Tipp, falls Befehlszeile länger als 127 Zeichen ist (dies ist eine bekannte Einschränkung vom 16-Bit-COMMAND.COM!): Temporäre .BAT generieren und diese ausführen, z.B.
Code: | OPEN ENVIRON$("TEMP") + "\~TEMP01.BAT" FOR OUTPUT AS 1
PRINT#1, "befehl /s1 /s2 arg1 arg2 arg3 arg4 arg5 arg6 arg7"
CLOSE 1
SHELL "cmd /c " + ENVIRON$("TEMP") + "\~TEMP01.BAT"
KILL ENVIRON$("TEMP") + "\~TEMP01.BAT" |
_________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
 |
triti
Anmeldungsdatum: 23.04.2009 Beiträge: 44
|
Verfasst am: 27.07.2009, 10:34 Titel: |
|
|
Hallo dreael !
> SHELL "cmd /c befehl /argumente"
tut bei mir nicht ganz, weil das Programm trotz /c auf DOS-Ebene hängenbleibt.
ABER:
Als Batch gehts!
open "c:\test.bat" for output as #1
print #1, "cmd /c rd/s/q c:\sicher.ung\01012009\"
print #1, "exit"
close #1
shell "cmd /c c:\test.bat"
Mit dem EXIT im batch komme ich wieder ins Programm zurück.
Schaut so aus, dass das Problem gelöst ist.
Vielen Dank euch
lg
Triti |
|
Nach oben |
|
 |
triti
Anmeldungsdatum: 23.04.2009 Beiträge: 44
|
Verfasst am: 27.07.2009, 12:47 Titel: |
|
|
Äh, eine Frage hab ich noch:
Gibts einen Trick, damit man mit shell "Sort ..." irgendwie Datum-Dateinamenliste nach dem DAtum sortieren, damit die älteste ganz oben (oder unten) steht?
Ich krieg das nicht hin. Der sortiert nicht richtig. /+n bringt in dem Fall auch nix.
So eine Liste:
04032009
17062010
01012009
01062009
02012009
23072009
30062010
12052009
Oder muss ich mir eine umständliche QB-Programm schreiben, das das macht? Erst mal in 2 Dateien schreiben für 2009 und 2010. So weit einfach. Aber dann?
lg
Triti |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 27.07.2009, 13:18 Titel: |
|
|
Schreib dir einfach ne Bubblesort-Routine, das ist der einfachste Algorithmus, den du finden kannst. Wenn du nicht weißt, was das ist, schau einfach auf Wikipedia nach... Auf qbasic.de gibt's aber sicher schon fertige Implementierungen von Quicksort, was wesentlich schneller ist.
Bevor du die Daten dann sortierst, musst du sie logisch umstrukturieren, nämlich in das Format YYYYMMDD (statt DDMMYYYY). Geht ja mit MID, LEFT und RIGHT ganz einfach... _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
triti
Anmeldungsdatum: 23.04.2009 Beiträge: 44
|
Verfasst am: 28.07.2009, 13:48 Titel: |
|
|
Ja gut, mache ich.
Danke,
T. |
|
Nach oben |
|
 |
Flo aka kleiner_hacker
Anmeldungsdatum: 23.06.2006 Beiträge: 1210
|
Verfasst am: 28.07.2009, 18:10 Titel: |
|
|
triti hat Folgendes geschrieben: | Hallo dreael !
> SHELL "cmd /c befehl /argumente"
tut bei mir nicht ganz, weil das Programm trotz /c auf DOS-Ebene hängenbleibt.
|
hat cmd nicht nen schalter, mit dem man es nach der ausführung des befehls zum beenden zwingt?
ich glaube, da mal sowas gesehen zu haben _________________ MFG
Flo
Satoru Iwata: Wer Spaß am Spielen hat, fragt nicht nach Grafik.
zum korrekten Verstaendnis meiner Beitraege ist die regelmaessige Wartung des Ironiedetektors unerlaesslich. |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 28.07.2009, 21:57 Titel: |
|
|
triti hat Folgendes geschrieben: | > SHELL "cmd /c befehl /argumente"
tut bei mir nicht ganz, weil das Programm trotz /c auf DOS-Ebene hängenbleibt. |
Zum Verständnis: "befehl /argument" ist natürlich nur stellvertretend für irgend einen richtige Befehl -> sollte also durch etwas "Richtiges" ersetzt werden, z.B. Deinem "rmdir /s"-Befehl...
triti hat Folgendes geschrieben: | print #1, "cmd /c rd/s/q c:\sicher.ung\01012009\" |
Innerhalb des Batchs braucht es kein vorangestelltes "cmd /c" - verschlingt nur unnötige Ressourcen in Form von Subprozessen.
triti hat Folgendes geschrieben: | print #1, "exit" |
Explizites "exit" braucht es ebenfalls nicht. Lediglich sinnvoll und empfehlenswert: stdout und stderr umleiten + Errorlevel ermitteln.
triti hat Folgendes geschrieben: | shell "cmd /c c:\test.bat" |
Dagegen hier (und nur hier) braucht es den "cmd /c"-Vorsatz. Dagegen würde ich den hard-coded Pfad wie "C:\" vermeiden (ich habe auch schon Windows-Installationen ohne Laufwerk C gesehen!) und stattdessen mit %TEMP% arbeiten.
Beispiel mit stdout und stderr:
Code: | OPEN ENVIRON$("TEMP") + "\~TMP01.BAT" FOR OUTPUT AS 1
PRINT#1, "befehl /argument >" + ENVIRON$("TEMP") + "\~STDOUT.TMP 2>" + ENVIRON$("TEMP") + "\~STDERR.TMP"
PRINT#1, "echo %ERRORLEVEL% >" + ENVIRON$("TEMP") + "\~ERRLV.TMP"
CLOSE 1
SHELL "cmd /c " + ENVIRON$("TEMP") + "\~TMP01.BAT"
KILL ENVIRON$("TEMP") + "\~TMP01.BAT"
' stdout verarbeiten
OPEN ENVIRON$("TEMP") + "\~STDOUT.TMP" FOR INPUT AS 1
WHILE NOT EOF(1)
LINE INPUT#1, z$
' z$ mit Stringfunktionen verarbeiten
WEND
CLOSE 1
KILL ENVIRON$("TEMP") + "\~STDOUT.TMP"
' stderr (Fehlermeldungen) verarbeiten
OPEN ENVIRON$("TEMP") + "\~STDERR.TMP" FOR INPUT AS 1
WHILE NOT EOF(1)
LINE INPUT#1, z$
' z$ mit Stringfunktionen verarbeiten
WEND
CLOSE 1
KILL ENVIRON$("TEMP") + "\~STDERR.TMP"
' Errorlevel einlesen
' stdout verarbeiten
OPEN ENVIRON$("TEMP") + "\~ERRLV.TMP" FOR INPUT AS 1
INPUT#1, errlv%
CLOSE 1
KILL ENVIRON$("TEMP") + "\~ERRLV.TMP" |
In Deinem Beispiel würde ich den Errorlevel auswerten, ob der "rmdir /s" überhaupt erfolgreich war oder nicht. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
 |
triti
Anmeldungsdatum: 23.04.2009 Beiträge: 44
|
Verfasst am: 29.07.2009, 16:50 Titel: |
|
|
Uff.
Danke für die Mühe. Ich werde versuchen zu verstehen was Du da geschrieben hast...
>... ob der "rmdir /s" überhaupt erfolgreich war oder nicht.
Äh ich hab mir einfach wieder mit dir /AD > dir.tmp eine Verzeichnisliste in eine Datei geschrieben und dort geschaut, obs immer noch da war.
War nicht. Weil: es funktioniert
lg
Triti |
|
Nach oben |
|
 |
|