Where do you want to go next?here's for you :)about homeopathyassorted rantsVB and subclassingVB, screensavers and security concernsLet the Skriptkiddiots play...VB and pointersVB and the Windows shellVB and multitaskingVisual Basiclibrariessnakeoil and blatant liesZoneAlarmeSafefirewall basicsabout harmful codeIn Commerce' Service - sniffersabout spywarecookie jarabout PGPabout privacymain page

Shell applications

From VB you won't be able to pass extended commandlines with switches to a shell app. That's where you take out your hammer: write a batch and call that. This works even for a pure Windows program, since Win will know how to handle it.


To watch these functions at work, download the LiDuS-code here.


MakeBatch takes the program to call and the switches as parameters. It writes the batch, but does not call it.


Private Sub MakeBatch(ProgName as String, _

Switches as String)

Dim f As Integer
Dim OutName As String

'let's find a name for the output-file

OutName = Left$(Progname, Instr(Progname, "."))


'does the batch exist? kill it anyway to _

'avoid misconceptions.


    If Dir(App.Path & "\doscall.bat") <> "" Then
        Kill App.Path & "\doscall.bat"
    End If


   'does the output-file exist? we don't need _

'it - yet
    If Dir(App.Path & OutName & ".txt") <> "" Then
        Kill App.Path & OutName & ".txt"
    End If


    'begin.tmp is a dummy. its deletion is the _

'last thing the batch does, telling us it's _

done.
    f = FreeFile
    Open App.Path & "\begin.tmp" For Output As f
        Print #f, "I'm worthless"
    Close f

    'so let's write the batch:
    f = FreeFile
    Open App.Path & "\doscall.bat" For Output As f
        Print #f, ProgName & " " & Switches & _

" > " & OutName & ".txt" & vbCrLf & _
        "del begin.tmp"
    Close f
End Sub


This function takes the program-name we provided MakeBatch with and returns the output the batch generated. Have a look at how we wait for the deletion of begin.tmp.


Private Function ReadOutput(ProgName As String) As String
Dim f As Integer
Dim OutName As String
Dim Dummy As Long

    'who's output are we going to read?
    OutName = Left$(ProgName, Len(ProgName) - 4)

    'wait for the worthless file to be deleted
    While Dir(App.Path & "\begin.tmp") <> ""
        DoEvents
    Wend

    'we have a hit!
    f = FreeFile
    Open App.Path & "\" & OutName & ".txt" For Input As f
        While Not EOF(f)
            ReadOutput = ReadOutput & Input$(1, f)
        Wend
    Close f
End Function


If the program you want to call is a DOS-programm (like ping) you will find your desktop cluttered with killed dosboxes. Don't throw an atom-bomb at them, just have a close look at COMSPEC.


Call Shell(Environ("COMSPEC") & " /C " & App.Path _

& "\doscall.bat", vbMinimizedNoFocus)


So how would we use these to ping a machine from VB without the user ever noticing? Mind, this works only for Windows 9x, not for Windows NT. The latter is somewhat picky when it comes to hiding activity from the user.


Public Function Ping(IP As String) As String
Dim Dummy As Variant
    MakeBatch "ping.exe", IP
    Call Shell(Environ("COMSPEC") & " /C " & _

App.Path & "\doscall.bat", _

vbMinimizedNoFocus)

    Ping = ReadOutput("ping.exe")
End Functiont


Neat, hu?


Another thing is passing windows the hot potato of handling a certain extension. Just call Shell.Execute with the file in question. Windows will know what to do with it and start the application that is associated. But be careful to handle any occuring errors: your user might not have the application installed :)