Link to home
Start Free TrialLog in
Avatar of dynomite082002
dynomite082002

asked on

How to tell VB accept parameter ?

Here is my way of openning the vb program :
C:\myVB.exe abc 123 This_is_a_test

At this time, myVB still open. When I issue
above cmd on MS-DOS, myVB should able to pick it
and do msgbox the parameter. Is that possible ?
Avatar of Monchanger
Monchanger
Flag of United States of America image


Microsoft's example function (can be found at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbenlr98/html/vafctcommandx.asp)

Function GetCommandLine(Optional MaxArgs)
   'Declare variables.
   Dim C, CmdLine, CmdLnLen, InArg, I, NumArgs
   'See if MaxArgs was provided.
   If IsMissing(MaxArgs) Then MaxArgs = 10
   'Make array of the correct size.
   ReDim ArgArray(MaxArgs)
   NumArgs = 0: InArg = False
   'Get command line arguments.
   CmdLine = Command()
   CmdLnLen = Len(CmdLine)
   'Go thru command line one character
   'at a time.
   For I = 1 To CmdLnLen
      C = Mid(CmdLine, I, 1)
      'Test for space or tab.
      If (C <> " " And C <> vbTab) Then
         'Neither space nor tab.
         'Test if already in argument.
         If Not InArg Then
         'New argument begins.
         'Test for too many arguments.
            If NumArgs = MaxArgs Then Exit For
            NumArgs = NumArgs + 1
            InArg = True
         End If
         'Concatenate character to current argument.
         ArgArray(NumArgs) = ArgArray(NumArgs) & C
      Else
         'Found a space or tab.
         'Set InArg flag to False.
         InArg = False
      End If
   Next I
   'Resize array just enough to hold arguments.
   ReDim Preserve ArgArray(NumArgs)
   'Return Array in Function name.
   GetCommandLine = ArgArray()
End Function


Which returns an array of variants (watch out for index 0, which is Empty)

To use your arguments in design time (when you debug), enter them in Project->Project Properties, "Make" tab -> "Command Line Arguments" (do not include the name of your .exe)
Avatar of dynomite082002
dynomite082002

ASKER

Monchanger,

The codes you pasted will only work as long as myVB
is not openning before I issue the cmd, right ?

What I want is - it will still able to get the parameter
while myVB is still exist on the desktop.
:-/
I'm sorry, but I didn't understand your last comment. Please explain what you mean. I'll venture a guess as to what you meant to hopefully save you some time.

Are you saying you want a shortcut on the desktop to contain the command line arguments ? If so, you can set the "Traget" property of the shortcut to "[EXE full path]" [arguments]

Sorry ! My English. Let me make an example.

First I issue CMD like :
C:\myVB.exe 123 abc
then it will open myVB at this point to display
123 and abc on the screen or in msgbox.
I don't close myVB.exe

Second, I reissue CMD again :
C:\myVB.exe 234 bcd
Same thing, I will see 234 and bcd on the screen or msgbox.

Is that possible ? What I know is - I have to close myVB
before I issue another CMD, right ?
But I don't want to close myVB.exe.
It sounds like you want to display the parameters in a msgbox when the application starts?

In form_load:

if Command$ <> "" then
   msgbox "Command line: " & Command$
end if

You can also parse them using the code from Monchanger.

Let us know if we are off base...
gencross,

if Command$ <> "" then
  msgbox "Command line: " & Command$
end if

Above code is what I am looking for, but it will only work
as long as myVB have not been openned yet.

myVB is openned all the time, and it cannot be closed.
It should not matter that an instance of your exe is already running.  If you start another instance of the exe with parameters it should display those.  

I have just tried this using the above code in a form load event and compiled an exe.  It works multiple times while leaving the EXE running.

Perhaps you could post some code, or give more info.
Only one instance of myVB can run at a time.
The only way I can think of to accomplish what you want is when you run the EXE check to see if there is another instance running already.  If so then kill it and run the new one, which will run using the new parameters.  Off the top of my head I do not know how this (killing) can be done.

Does this sound like it will work for you?
Avatar of Mike McCracken
Do you possibly have code that precludes a second instance of the program starting?

We do that on a database program we have to prevent the user from updating records from multiple instances.

mlmcc
gencross,

I like your idea. What I have right now is preventing a new
myVB from running which is opposite of your idea.

Do you have code for your idea ?
Private Sub Form_Load()
    MsgBox Command
    If App.PrevInstance Then
        Unload Me
    End If
End Sub

Have a look at the code given above.

It works fine. However, in this case the latest instance is killed and the first one keeps running. Your requirement of just one instance running at a time is satisfied, but i don't know how exactly you want it to happen.

This is probably way to hard to bother with, and I can't help you with the code but...

in the example:
If app.PrevInstance then
  Unload Me
end if

In front of unload do a :
SendMessage Special Message,to previnstance, Command

and have your program listen to the messages looking for Special Message, and acting appropriately.

Sorry I'm not more specific on how, I haven't had reason to write a app that talks to other apps.
ventond,

You have mentioned about SendMessage. But
what API should I use to tell myVB listen to the message ?

p/s: winsock is not an option.
Use DDE to link to your previous application and send the commandline parameters.
Have a look at the question TimCottee answered for me just a few days ago. This is surely what you need. I'm sorry the question is already PAQ, but copy and paste would not be fair, I think.

This is a solution using DDE. It worked for me.

https://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=visualbasic&qid=20303531

zzconsumer, you can repost it if you like. As you say this is the solution for this problem as well.
Thanks. Here it is:

Change TDDE to the name of your executable, add two textboxes and set the form's property 'LinkMode' to 'source'.

Private Sub Form_Load()
 If App.PrevInstance Then
     Text2.LinkTopic = "TDDE|Form1"
     Text2.LinkItem = "Text1"
     Text2.LinkMode = vbLinkAutomatic
     Text2.Text = Command()
     Text2.LinkPoke
     End
 End If
End Sub

Private Sub Text1_Change()
 MsgBox Text1.Text
 ' In Text1.Text, the passed parameter is now in.
End Sub

You may do it with one TextBox as I finally did, but this way you avoid any possible confusion.

dynomite, sounds like you have a good solution now.  

I hope it works for you.
MCummings and zzconsumer,

I have thought of DDE, but will work because dde server and client is the same EXE ?
It will indeed work because they are not the "Same" executable, merely seperate instances of it. The situation zzconsumer was in was in respect of selecting multiple files in explorer and opening them all with his application. In this case there are potentially hundreds of instances of the application all open for a short time. Even in this case this works happily as the DDE connection is always to the first registered instance of the application. You could test this using DDE-SPY to determine that subsequent registrations as a DDE server by the subsequent instances actually fails because a DDE server already exists.
Problem !

This is what I have :

Private Sub Form_Load()
Text1.Text = "1"   'Initialize
If App.PrevInstance Then
    Text2.LinkTopic = "project1|Form1"
    Text2.LinkItem = "Text1"
    Text2.LinkMode = vbLinkAutomatic
    Text2.Text = Command()
    Text2.LinkPoke
    End
Else
  Text1.Text = Command()
End If
End Sub


Private Sub Text1_Change()
Print Text1.Text
End Sub


when I called C:\project1.exe 123 for the first time, I saw
123in text1.text, but it did not print 123 on the form.

when I called it for the 2nd time C:\project1.exe abc, I saw abc in text1.text and printed on the form.

How do I make it printed for the 1st time ?
when can I get DDE-Spy ?
Make sure that the form is clear the first time, in your form_load do Me.Cls to reset the current print position.

DDE-spy comes with MS Visual Studio 6 full install, if you have this then it is in the tools folder. It will show you all the DDE conversations and messages that are being used. You may find that there is a lot of stuff there that is not entirely clear (I did to start with). But you can get the sense of what is going on by studying these messages.
I found out something else about App.PrevInstance property, which i didn't know before.

As long as the ONLY instance of an APP is running the property returns FALSE. However, when another instance starts executing, property value in BOTH instances changes to TRUE.

In light of this, are you ready to consider some sort of loop which keeps checking for change in this value and then terminates the APP?

If yes, please let me  know. I might spend some time writing such a loop.

Drawback of this approach is Performance!
TimCotte,

I put Me.Cls before Text1.Text = "1"   'Initialize.
I still cannot see it for the 1st time.
I do initialize the text1.text from the beginning, and
Private Sub Text1_Change() should pick it up, right ?
ASKER CERTIFIED SOLUTION
Avatar of TimCottee
TimCottee
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial