Jag vill från vb eller vbs starta ett program eller en bat-fil och vänta tills exekveringen är färdig och programmet är avslutat, innan jag går vidare i koden. Någon som har ett bra tips? Enl denna principlösning är en av metoderna När programmet är färdigstartat kommer ret att innehålla ProcessId för Här kanske du kan få en idé. SvenPon: Om jag förstår rätt så skulle din kod alltså starta programmet och sedan när programmet var startat så skulle koden fortsätta? Problemet är ju att loopen i så fall är onöig eftersom att vb inte kommer att fortsätta förrens programmet är startat... >onöig eftersom att vb inte kommer att fortsätta förrens programmet är startat... >>onöig eftersom att vb inte kommer att fortsätta förrens programmet är startat... Uppriktigt sagt, jag förstår inte vad du svamlar om. Sven. >Med din lösning så kommer Msg-Boxen upp när Notepad har startats men enligt Nja, <förrutom att om Shell-kommandot misslyckas, ret=0, i ditt fall så hamnar du i en <evighetsloop med ditt Do Until Om det tar 10 sek att ladda programmet så kommer inte shell att fortsätta förrens efter 10 sek Helt säker kan man inte vara i VB, eftersom referenser döljs på ett helt annat sätt än i andra språk. Vad gäller just tilldelningar är jag dock tämligen säker på att det bara sker just en gång. Hm... Den får ju ingen referens till variabeln, vb tar ju bara emot värdet och kopierar det till ret? Eller? Så om den skulle få tag på en minnesadress så skulle det ju inte vara adressen till ret ju... Nej, jag säger ju det. I det här fallet är det förmodligen inte så (även om VB skulle kunna ha en del hyss för sig man inte märker). Då ja, men en long är en long... ;) Och jag tror inte att vb göra sådana saker... har inte hört talas om det iaf... :) >Kan du förklara hur in i sjutton ret skulle kunna få ett nytt värde när den sitter i loopen och kör? Jag kommer nog ihåg fel. Får ta fram mina "Dödahavsrullar" och kolla. Det där med loopen stämmer nog, men du måste anropa ett api däri också där du sätter ret till resultatet utav det...Starta och vänta (VB6/VBS)
Sv: Starta och vänta (VB6/VBS)
<code>
Dim ret As Long
ret = Shell("C:\Windows\NotePad.exe",vbNormalFocus)
Do Until ret <> 0
DoEvents
Loop
</code>Sv: Starta och vänta (VB6/VBS)
det startade programmet dvs <> 0 och loopen bryts programmet går vidare.
Ev får du sätta ret = 0 direkt efter ifall du skall öppna fler prog på detta vis.Sv: Starta och vänta (VB6/VBS)
vbnet.mvps.org/faq/main/waitforsingleobject2.htm
//
JanneSv: Starta och vänta (VB6/VBS)
Sv: Starta och vänta (VB6/VBS)
Har du lässvårigheter ?
> Jag vill från vb eller vbs starta ett program eller en bat-fil och vänta tills exekveringen är färdig
Skrev frågeställaren.!
Enl honom så vill han att VB skall göra halt i programkörningen tills Shell kommandot
är utfört. Tycker att Jan:s lösning är mycket proffsigare än min gamla Vb 3 lösning.Sv: Starta och vänta (VB6/VBS)
>Har du lässvårigheter ?
Nej, jag har inga lässvårigheter... Du skrev:
>>
När programmet är färdigstartat kommer ret att innehålla ProcessId för
det startade programmet dvs <> 0 och loopen bryts programmet går vidare.
Ev får du sätta ret = 0 direkt efter ifall du skall öppna fler prog på detta vis.
<<
Dvs. när programmet har startats så kommer ret att innehålla processid... Problemet är ju bara att loopen har ingen som helst funktion eftersom att ret aldrig kommer att ändras efter anropet... Sluta gapa så dant... Enda möjligheten för loopen att köras är om försöket att starta programmet misslyckas, då får du 0 (iaf. med shellexecute), och då kommer loopen att gå i all oändlighet...Sv: Starta och vänta (VB6/VBS)
<code>
Option Explicit
Private Sub Command1_Click()
Dim ret As Long
ret = Shell("C:\Windows\NotePad.exe", vbNormalFocus)
Do Until ret <> 0
DoEvents
Loop
MsgBox "NotePad har startat Ok jag kan gå vidare med min Vb code"
End Sub
</code>Sv: Starta och vänta (VB6/VBS)
Med din lösning så kommer Msg-Boxen upp när Notepad har startats men enligt original frågan så ska den visas när Notepad har körts färdigt (avslutats).
Ett sätt att få till den funktionen på är
<code>
Option Explicit
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const STATUS_PENDING = &H103&
Private Sub main()
Dim hProcess As Long
Dim ProcessId As Long
Dim exitCode As Long
ProcessId = Shell("notepad.exe", vbNormalNoFocus)
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId)
Do
Call GetExitCodeProcess(hProcess, exitCode)
DoEvents
Loop While exitCode = STATUS_PENDING
Call CloseHandle(hProcess)
MsgBox "'Shell'-programmet har avslutats."
End Sub
</code>
//
JanneSv: Starta och vänta (VB6/VBS)
>original frågan så ska den visas när Notepad har körts färdigt (avslutats).
Ok kanske lite "massuppfittning" Men följande tankeexperiment MittDok är 5 MB
<code>
Dim ret As Long
ret = 0
ret = Shell("C:\Program\Micrsoft Office\WinWord.exe MittDok.doc", vbNormalFocus)
Do Until ret <> 0
DoEvents
Loop
MsgBox "Nu är MittDoc laddat"
End Sub
</code>
Dvs När Word har laddat MittDok (kanske 3-4 sek) så blir ret <> 0 Eller ?Sv: Starta och vänta (VB6/VBS)
ret får ju sitt värde när raden
<code>ret = Shell("C:\Program\Micrsoft Office\WinWord.exe MittDok.doc", vbNormalFocus)</code>körs.
ret blir <> 0 om Shell-kommandot lyckas när du senare i koden kör
<code>
Do Until ret <> 0
DoEvents
Loop
</code>
Så gör du egentligen bara en koll om Shell-lyckades eller inte. Det är inte så att ret först är 0 och sen när ditt dokument laddats ändrar sig till <> 0 utan ret får sitt värde just när raden med shellkommandot exekveras och shell-kommandot körs normalt asynkront och det är därför VB programmet fortsätter direkt.
Som du skrivit ditt exempel så är det egentligen ingen skillnad från följande
<code>
If ret <> 0 Then
DoEvents
End If
</code>förrutom att om Shell-kommandot misslyckas, ret=0, i ditt fall så hamnar du i en evighetsloop med ditt Do Until
//
JanneSv: Starta och vänta (VB6/VBS)
Mmm.... Det här är ju inget jag hittat på utan kommer från gamla experters Tips o Trix
Som du förstår så håller jag med om att din lösning är proffsigare.
beträffande felhantering så kan du ju alltid komma ur loopen eftersom DoEvents finns
jag utgick från att den skulle lyckas. Klart att man måste hantera Error.
"If the Shell function successfully executes the named file, it returns the task ID of the
started program. The task ID is a unique number that identifies the running program.
If the Shell function can't start the named program," *an error occurs*.
Jag hävdar att om i mitt exempel det tar 10 sek att ladda Worddokumentet
så kommer ret inte bli <> 0 förrän efter 10 sek .
Så uppfattade jag att frågeställaren ville ha det.Sv: Starta och vänta (VB6/VBS)
Alt. att programmet kommer att fortsätta ändå, men loopen kommer aldrig att köras...
Kan du förklara hur in i sjutton ret skulle kunna få ett nytt värde när den sitter i loopen och kör?Sv: Starta och vänta (VB6/VBS)
Men betänk följande:
Du har ett WinAPI-anrop (eller något annat externt), vi kallar den X, som tar en pekare till en Long (den Long som finns i VB).
Någon har gjort en wrapper till detta anrop. Vi kan kalla wrappern för Y.
Y har en inparameter som är ByRef och av typen Long, vi kallar den Z. Y skickar nu adressen av Z till X, (kanske gör något mer, det är oväsentligt) och avslutar sig själv.
Hur har X använt den Long som skickades in?
Det kan vara så att X kommer att behålla adressen till Z, och sedan ändra den när något har inträffat, eller vid ett annat API-anrop, osv.
Z kommer då hamna i ett s.k. "volatile-läge", man vet bara dess värde just när man kollar i den.
I t.ex. C/C++ finns ett speciellt nyckelord (volatile) för sådana variabler.
Det kan alltså (åtminstone teoretiskt) vara så att båda If-satserna nedan kommer att utföras (men det sker naturligtvis mycket sällan).
If a=1 Then
'Gör sak 1
End If
If a=2 Then
'Gör sak 2
End If
Men som sagt: I det här fallet verkar det mycket orimligt.Sv: Starta och vänta (VB6/VBS)
Sv: Starta och vänta (VB6/VBS)
Om man istället hade haft något i stil med:
Set A = Funktion(Argument)
Så hade samma sak kunnat hända.Sv: Starta och vänta (VB6/VBS)
Sv: Starta och vänta (VB6/VBS)
NejSv: Starta och vänta (VB6/VBS)
Det handlade om simulerad multitasking där den ena processen väntade
tills den andra blev True. Man löste det med Do Loopar och DoEvents.Sv: Starta och vänta (VB6/VBS)