svenguenter
Goto Top

CMD öffnen, offen halten und befehl übergeben

Hallo foglendes Problem.
Ich will aus einem VB6 Programm eine shell öffnen einen befehl schon vorgeben aber noch NICHT absenden. Sprich der User soll noch möglichkeiten zum editieren haben.

Ich habe schon was gemacht aber leider schließt sich die cmd sofort wieder wenn ich diese mit

SHELL programm,vbnormalsize

anspreche

in programm ist der String hinterlegt. Als Beispiel "echo C:\Programme\Verzeichnis\programm.exe"

Der exe kann aber noch ein oder mehrere Parameter übergeben werden, weswegen diese nicht gestaret werden soll.
Gibt es da einen Schalter den ich setzen muss oder wie mach ich das am besten?


Gruß

Sven

Content-ID: 78287

Url: https://administrator.de/contentid/78287

Ausgedruckt am: 24.11.2024 um 17:11 Uhr

bastla
bastla 16.01.2008 um 11:56:32 Uhr
Goto Top
Hallo SvenGuenter!

Warum nicht dem Benutzer eine InputBox anbieten und dann die vollständige Parameter-Zeile an den Batch übergeben?

Eine etwas abenteuerliche Variante könntest Du über "SendKeys" versuchen.
Wenn Du das CMD-Fenster (bis zur Ausführung eines "exit"-Befehles - egal ob durch Benutzereingabe oder per Batch) offen halten willst, dann mit "cmd /k" aufrufen - dazu kannst Du auch gleich einen (sofort auszuführenden) Befehl angeben, etwa
objShell.Run "cmd /k cd /d D:\Test"  

Grüße
bastla
SvenGuenter
SvenGuenter 16.01.2008 um 12:07:34 Uhr
Goto Top
problem ist das die cmd sich schließt auch wenn sie offen bleiben soll.

z.B muss bei einer *.exe im nachhinein noch ein passwort eingegeben werden, was ich aber nicht mit dem ersten string erledigen kann.

Ich habe das ja auch so gemacht. Sprich textfeld welches ich auslese und dann der shell übergebe was ich halt nicht hinbekomme das das Dosfenster aufbleibt nachdem der befehl abgesetzt wurde.
SvenGuenter
SvenGuenter 16.01.2008 um 12:12:38 Uhr
Goto Top
Hallo SvenGuenter!

Warum nicht dem Benutzer eine InputBox
anbieten und dann die vollständige
Parameter-Zeile an den Batch übergeben?

Eine etwas abenteuerliche Variante
könntest Du über
"SendKeys" versuchen.
Wenn Du das CMD-Fenster (bis zur
Ausführung eines
"exit"-Befehles - egal ob durch
Benutzereingabe oder per Batch) offen halten
willst, dann mit "cmd /k" aufrufen
- dazu kannst Du auch gleich einen (sofort
auszuführenden) Befehl angeben, etwa
objShell.Run "cmd /k cd /d  
> D:\Test"  
> 

Grüße
bastla

das objshell referentierst du worauf?
bastla
bastla 16.01.2008 um 12:20:05 Uhr
Goto Top
Hallo SvenGuenter!

Sorry, war noch in VBScript - dort:
Set objShell = WScript.CreateObject("WScript.Shell")  
In VB6 genügt natürlich ein "Shell".

Grüße
bastla
SvenGuenter
SvenGuenter 16.01.2008 um 12:31:23 Uhr
Goto Top
super das geht schonmal einwandfrei und wie übergebe ich nun an die cmd einfach nur einen befehl ohne das dieser ausgeführt wird. Oder einfach nur Zeichen?
bastla
bastla 16.01.2008 um 14:17:36 Uhr
Goto Top
Hallo SvenGuenter!

... wie übergebe ich nun an die cmd einfach nur einen befehl ohne das dieser ausgeführt wird
Abgesehen vom oben erwähnten "SendKeys" eigentlich gar nicht ...

... wobei ich mir nicht sicher bin, dass die angestrebte Vorgangsweise nötig ist - immerhin kennt Batch ja zumindest eine Input-Möglichkeit über
set /p "Eingabe=Parameter angeben: "  
echo Eingegeben wurde: %Eingabe%

Grüße
bastla
SvenGuenter
SvenGuenter 16.01.2008 um 15:44:44 Uhr
Goto Top
Hi Ich bekomme die Motten.

Also ich habe folgendes verscuht

Versuch 1.
Option Explicit
Public befehlshilfe As String
Private Declare Function WriteConsole Lib "kernel32" Alias _  
        "WriteConsoleA" (ByVal hConsoleOutput As Long, ByVal _  
        lpBuffer As Any, ByVal nNumberOfCharsToWrite As Long, _
        ByRef lpNumberOfCharsWritten As Long, lpReserved As Long) As Long
        

Private Declare Function AllocConsole Lib "kernel32" () As Long  
Private Declare Function FreeConsole Lib "kernel32" () As Long  
Private Const STD_OUTPUT_HANDLE As Long = -11&
Private hConsoleIn As Long
Private hConsoleOut As Long
Private hConsoleErr As Long
Private Declare Function GetStdHandle Lib "kernel32" _  
        (ByVal nStdHandle As Long) As Long
Private Declare Function sleep Lib "kernel32" (ByVal dwMilliseconds&)  


'******************************************************************  
'Klickereignis und dann soll es passieren  
'******************************************************************  
Private Sub button_programmstarten_Click()

    Call AllocConsole
    
    shell "C:\Programm.exe" , vbnormalfocus  
    
    hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE)
    Call ConsolePrint("Hallo, wer immer Du auch bist!" & vbCrLf)  


Me.button_cancel.Caption = "Beenden"  
End Sub

Private Sub ConsolePrint(szOut As String)
    Dim BytesWritten As Long
    
    Call WriteConsole(hConsoleOut, szOut, Len(szOut), BytesWritten, 0&)
End Sub

erfolg? Nein er macht ein neues cmd auf und schreibt mir da schön den text rein.
Also ich nicht dumm und nciht faul sendkeys angeschaut und folgendes gebastelt

'******************************************************************  
'Klickereignis und dann soll es passieren  
'******************************************************************  

Private Sub button_programmstarten_Click()
Dim programm As String
Dim progid


programm = Me.txtcommand
progid = Shell(programm, vbNormalFocus)
'******************************************************************  
'Schleife damit Progid auch sicher gefüllt ist  
'******************************************************************  

Do
If progid <> 0 Then Exit Do
sleep (50)
Loop
'******************************************************************  
'Cmdfnester als aktive App setzen  
'******************************************************************  

AppActivate progid, 1
'******************************************************************  
'Zu sendende Zeichen  
'******************************************************************  

SendKeys "abc", 1  
Me.button_cancel.Caption = "Beenden"  
End Sub
'******************************************************************  
'^Benötigte globale function sleep im allgemeinen Teil declariert  
'******************************************************************  
Private Declare Function sleep Lib "kernel32" (ByVal dwMilliseconds&)  



Tja auch das Funktioniert nicht. Bin mit meinem Latein langsam am ende. Wenn ich bei der shell das Programm mitgebe wird das Programm gestartet und bei appactivate steigt das programm aus weil ich angeblich die prozedur falsch aufrufe oder ein fehlerhaftes argument habe.

Ich hoffe es kann mir einer helfen.


edit

Kleine kuriosität. Ich habe eine Messagebox eingebaut das ich sehe welche progid ich habe. Wenn ich diese direkt nach dem erscheinen wegklicke bekommt meine Dosbox den SendKey. WEnn ich diese msgbox wegnehme bekomme ich einen Fehler bei AppActivate
bastla
bastla 16.01.2008 um 18:57:59 Uhr
Goto Top
Hallo SvenGuenter!

Es fällt mir weiterhin schwer, die Notwendigkeit der von Dir angedachten Vorgangsweise zu erkennen. Sieh Dir vielleicht einmal den folgenden Versuch mit einem Startbatch und einem, das Programm simulierenden, weiteren Batch an - in beiden Batchdateien wird dem Benutzer die Möglichkeit gegeben, an der Konsole eine Eingabe zu tätigen, obwohl der erste Batch direkt (also ohne explizites Öffnen einer CMD-Shell) gestartet wird:

VB6
Private Sub btnStart_Click()
Shell "D:\Starter.cmd Param1 Param2 ""Param 3"" Param4", vbNormalFocus  
End Sub

Batch "D:\Starter.cmd"
@echo off & setlocal
set /p "Zusatz=Weiterer Parameter (neben %*): "  
D:\Prog.cmd %* "%Zusatz%" "und noch ein Parameter"  

Batch "D:\Prog.cmd"
@echo off & setlocal
echo.
echo Prog.cmd
echo Parameter waren: %1_%2_%3_%4_%5_%6_%7_%8_%9
echo.
echo bzw ohne Anfuehrungszeichen:
echo Parameter waren: %~1_%~2_%~3_%~4_%~5_%~6_%~7_%~8_%~9
echo.
set /p "Passwort=Bitte Passwort eingeben: "  
echo Eingegebens Passwort: %Passwort%
echo.
pause

Sollte aus irgendeinem Grund das CMD-Fenster weiterhin benötigt werden, dann:
Private Sub btnStart_Click()
Shell "cmd /k D:\Starter.cmd Param1 Param2 ""Param 3"" Param4", vbNormalFocus  
End Sub

Grüße
bastla
SvenGuenter
SvenGuenter 17.01.2008 um 11:05:45 Uhr
Goto Top
hi basta danke für deine Hilfe. Ich habe das jetzt erstmal anders geläst da ich das Programm fertig machen will und muss. Hintergrund ist folgender.

Es wird eine Datei ausgelesen die alle User mit Computernamen beinhaltet.

Falls ein User bei uns in der EDV anruft können wir nun diese Datei auslesen den Computernamen erfahren und mit den Sysinternal Tools auf den Rechner ( verbindung bekommt man auch wenn man will mit UltraVNC ) zugreifen.
Damit man nun nicht immer schauen muss welche Parameter der einzelne Befehl hat und wie er geschrieben wird habe ich ein Programm gebaut welches diese Befehle sucht und übernimmt. Mit einem Klick auf ein Datagrid bekommt man den Computernamen des users. Nun kommt der Teil mit der CMD
Der befehl den ich anklicke wird nun an die cmd gesendet und die cmd muss aufbleiben da es Tols gibt die sich immer wieder refreshen.
Nun war es aber so das den befehl den ich an die CMD gesendet habe via shell "cmd /K pslist.exe -s", vbnormalfocos als Beispiel, nicht in der CMD zur Verfügung hatte. Sprich die CMD hat diesen nicht gespeichert gehabt. Nun wollte ich das der Befehl einfach nochmal im CPROMPT steht. Dies wollte ich halt mit SendKeys oder ähnlichem sofort nach dem Befehl machen. Das klappte leider nicht. Nun habe ich das mit einem extra Button gemacht und da funktioniert das dann auch mit dem AppActivate. Irgendwie ist die CMD für eine gewisse Zeit für SendKeys nicht empfangsbereit.

Ist aber auch kein Problem da es so nun per Knopfdruck geht.

Falls ich mal eine Lösung finde das komplett Automiatisch zu machen werde ich das hier posten. Ich kann mir durchaus vorstellen das ich irgendwie den aktivitätsstatus der shell auslesen muss.


Gruß

Sven