Results 1 to 21 of 21

Thread: [RESOLVED] How to pass values into a running program?

  1. #1

    Thread Starter
    Frenzied Member MrGTI's Avatar
    Join Date
    Oct 2000
    Location
    Ontario, Canada
    Posts
    1,277

    Resolved [RESOLVED] How to pass values into a running program?

    Hello.

    I'd like to pass some values into a VB6 application. I know how to do this via the command line, but what if the program is already running?

    Is there a way to send command line arguments to a running VB6 program? And if so, how does that work? Or, is there a better way to send the arguments to the running program?

    I welcome any comments. I have never tried to do this before so I would like some ideas on the best way to do it.

    Thanks.
    ~Peter


  2. #2

  3. #3
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: How to pass values into a running program?

    DDE, Winsock are good methods as long as you have the source code to both VB6 programs. If not, then, we'll have to figure out some other way


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  4. #4
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How to pass values into a running program?

    The demo project here shows yet another method using the WM_COPYDATA message.


    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  5. #5

    Thread Starter
    Frenzied Member MrGTI's Avatar
    Join Date
    Oct 2000
    Location
    Ontario, Canada
    Posts
    1,277

    Re: How to pass values into a running program?

    TheTrick - I am not familiar with the DDE, MAPI, FileMapping methods. I will have to do a little research to learn about it to see if I can use any of those methods.

    jmsrickland - I have the code for the VB.NET source program and the VB6 destination program, so yes, I'm sure we can find something to make it happen.

    BonnieWest - I will download and try the demo project. Thank you.
    ~Peter


  6. #6
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,797

    Re: How to pass values into a running program?

    I make simple example using FileMapping. You should compile and launch several instances of application and try to send message.
    Code:
    Option Explicit
    
    Private Type SharedData
        AppCount    As Long ' Count of running applications
        Counter     As Long ' Counter that show how many objects read data
        SenderPID   As Long ' Sender process id
        ' String offset ---- 0xc
    End Type
    
    Private Declare Function CreateFileMapping Lib "kernel32" _
                             Alias "CreateFileMappingA" ( _
                             ByVal hFile As Long, _
                             ByRef lpFileMappingAttributes As Any, _
                             ByVal flProtect As Long, _
                             ByVal dwMaximumSizeHigh As Long, _
                             ByVal dwMaximumSizeLow As Long, _
                             ByVal lpName As String) As Long
    Private Declare Function MapViewOfFile Lib "kernel32" ( _
                             ByVal hFileMappingObject As Long, _
                             ByVal dwDesiredAccess As Long, _
                             ByVal dwFileOffsetHigh As Long, _
                             ByVal dwFileOffsetLow As Long, _
                             ByVal dwNumberOfBytesToMap As Long) As Long
    Private Declare Function UnmapViewOfFile Lib "kernel32" ( _
                             ByVal lpBaseAddress As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" ( _
                             ByVal hObject As Long) As Long
    Private Declare Function CreateMutex Lib "kernel32" _
                             Alias "CreateMutexA" ( _
                             ByRef lpMutexAttributes As Any, _
                             ByVal bInitialOwner As Long, _
                             ByVal lpName As String) As Long
    Private Declare Function WaitForSingleObject Lib "kernel32" ( _
                             ByVal hHandle As Long, _
                             ByVal dwMilliseconds As Long) As Long
    Private Declare Function ReleaseMutex Lib "kernel32" ( _
                             ByVal hMutex As Long) As Long
    Private Declare Function lstrlen Lib "kernel32" _
                             Alias "lstrlenA" ( _
                             ByVal lpString As Any) As Long
    Private Declare Function lstrcpyn Lib "kernel32" _
                             Alias "lstrcpynA" ( _
                             ByVal lpString1 As Any, _
                             ByVal lpString2 As Any, _
                             ByVal iMaxLength As Long) As Long
    Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
                             
    Private Declare Sub CopyMemory Lib "kernel32" _
                        Alias "RtlMoveMemory" ( _
                        ByRef Destination As Any, _
                        ByRef Source As Any, _
                        ByVal Length As Long)
    Private Declare Sub ZeroMemory Lib "kernel32" _
                        Alias "RtlZeroMemory" ( _
                        ByRef Destination As Any, _
                        ByVal Length As Long)
    
    Private Const FILE_MAP_WRITE          As Long = &H2
    Private Const PAGE_READWRITE          As Long = 4&
    Private Const INVALID_HANDLE_VALUE    As Long = -1
    Private Const INFINITE                As Long = -1&
    Private Const ERROR_ALREADY_EXISTS    As Long = 183&
    
    Dim lpAddrSharedData    As Long ' Address of shared data
    Dim hMutex              As Long ' Synchronization mutex
    Dim IsSending           As Boolean
    Dim hMap                As Long
    
    Private Sub cmdSend_Click()
        Dim Dat     As SharedData
        
        ' Capture mutext
        WaitForSingleObject hMutex, INFINITE
        
        CopyMemory Dat, ByVal lpAddrSharedData, Len(Dat)
        
        If Dat.Counter > 0 Then
            MsgBox "Sending"
        Else
            ' Exclude itsels
            Dat.Counter = Dat.AppCount - 1
            Dat.SenderPID = GetCurrentProcessId()
            lstrcpyn lpAddrSharedData + &HC, ByVal txtMessage.Text, Len(txtMessage.Text) + 1
            CopyMemory ByVal lpAddrSharedData, Dat, Len(Dat)
            IsSending = True
        End If
        
        ' Release mutex
        ReleaseMutex hMutex
        
    End Sub
    
    Private Sub Form_Load()
        Dim Dat     As SharedData
        Dim isFirst As Long
        
        hMap = CreateFileMapping(INVALID_HANDLE_VALUE, ByVal 0&, PAGE_READWRITE, 0, &H1000, "MapExample")
        
        If hMap = 0 Then
            MsgBox "Unable to create file mapping", vbCritical
            End
        Else
            If Err.LastDllError <> ERROR_ALREADY_EXISTS Then
                ' First application
                isFirst = True
            End If
        End If
        
        lpAddrSharedData = MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0)
        
        If lpAddrSharedData = 0 Then
            MsgBox "Unable to project file mapping", vbCritical
            End
        Else
            If isFirst Then
                ' Clear all data
                ZeroMemory ByVal lpAddrSharedData, &H1000
            End If
        End If
        
        hMutex = CreateMutex(ByVal 0&, 0, "MapExampleMutex")
        
        If hMutex = 0 Then
            MsgBox "Unable to create mutex", vbCritical
            UnmapViewOfFile lpAddrSharedData
            End
        End If
        
        ' Capture mutext
        WaitForSingleObject hMutex, INFINITE
        
        CopyMemory Dat, ByVal lpAddrSharedData, Len(Dat)
        ' Add application
        Dat.AppCount = Dat.AppCount + 1
        CopyMemory ByVal lpAddrSharedData, Dat, Len(Dat)
        
        ' Release mutex
        ReleaseMutex hMutex
        
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        Dim Dat         As SharedData
        
        ' Capture mutext
        WaitForSingleObject hMutex, INFINITE
        
        CopyMemory Dat, ByVal lpAddrSharedData, Len(Dat)
        ' Delete application
        Dat.AppCount = Dat.AppCount - 1
        CopyMemory ByVal lpAddrSharedData, Dat, Len(Dat)
        
        ' Release mutex
        ReleaseMutex hMutex
        
        UnmapViewOfFile lpAddrSharedData
        CloseHandle hMap
        CloseHandle hMutex
    End Sub
    
    Private Sub tmrSurvey_Timer()
        Dim Dat         As SharedData
        Dim SizeOfStr   As Long
        Dim tmpString   As String
        Static LastData As Long
        
        ' Capture mutext
        WaitForSingleObject hMutex, INFINITE
        
        CopyMemory Dat, ByVal lpAddrSharedData, Len(Dat)
        
        ' Check sended data
        If Dat.Counter > 0 And Not IsSending Then
            If LastData = 0 Then
                ' We hava a new message
                SizeOfStr = lstrlen(lpAddrSharedData + &HC)         ' Get size of string
                tmpString = Space(SizeOfStr)                        ' Alloc space for string
                lstrcpyn ByVal tmpString, lpAddrSharedData + &HC, SizeOfStr + 1 ' Copy shared string to local string
                txtMessage = tmpString
                lstLog.AddItem "Get string '" & tmpString & "' from " & Dat.SenderPID
                ' Decrement counter
                Dat.Counter = Dat.Counter - 1
                
                CopyMemory ByVal lpAddrSharedData, Dat, Len(Dat)
            End If
            LastData = Dat.Counter
        Else
            If Dat.Counter = 0 Then IsSending = False
            LastData = 0
        End If
           
        ' Release mutex
        ReleaseMutex hMutex
        
    End Sub
    Attached Files Attached Files

  7. #7
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: How to pass values into a running program?

    Here's a sample of a very simple DDE demo
    Attached Files Attached Files


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  8. #8
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: How to pass values into a running program?

    Here's another example using Handles

    EDIT: Made correction to project
    Attached Files Attached Files
    Last edited by jmsrickland; Jun 24th, 2015 at 09:32 PM.


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  9. #9
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: How to pass values into a running program?

    Trying to make DDE work in .Net was so clunky Microsoft ended up punting and now refers to DDE as legacy technology and spits on it whenever they can. The old "baby can't eat steak so we all get pablum" syndrome mixed with a lot of sour grapes. But you face this sort of thing whenever you use a foreign layer on top of any OS, and .Net is no exception.

    As far as I know it can only be done using a hack like NDde which was never really supported.

    So DDE isn't practical if .Net is in the picture, even though it is still widely supported by native applications written in C, C++, VB6, etc. including the MS Office suite.

  10. #10
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How to pass values into a running program?

    Quote Originally Posted by Bonnie West View Post
    Yet another solution that you might find a lot easier ... was demonstrated in VB - Send a string between VB-created apps without using subclassing.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  11. #11
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: How to pass values into a running program?

    That's basically the same thing posted in #8
    Last edited by jmsrickland; Jun 24th, 2015 at 07:46 PM.


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  12. #12

    Thread Starter
    Frenzied Member MrGTI's Avatar
    Join Date
    Oct 2000
    Location
    Ontario, Canada
    Posts
    1,277

    Re: How to pass values into a running program?

    Wow. Thanks!

    I had a busy day and was in meetings for most of it. I will have to try to download and try all of these. There are certainly way more options than I expected!

    I'll check it out and reply back.
    ~Peter


  13. #13
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: How to pass values into a running program?

    I made a correction to project in post 8


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  14. #14
    Wall Poster TysonLPrice's Avatar
    Join Date
    Sep 2002
    Location
    Columbus, Ohio
    Posts
    3,969

    Re: How to pass values into a running program?

    I was very interested in seeing this work ( app in post #8) but it doesn't seem to for me. At least the way I imaged it would. "Click on App1 Command1' does not appear to work nor does "Click on App1 Command2'. I expected App1 to display "Left command button clicked" and so on. Sending text doesn't appear to work either. I'm on Windows 7 Professional.

    One last "anomaly" is clicking App2 "copy picture to App1 Picture1" put the picture in the upper left hand corner of my screen, not on the app.

    I was hoping it just worked "out of the box" to show to someone else I thought would be interested. I don't have time to try and debug it myself, at least in the near future.

    Edit:

    I had the apps split across two monitors and thought that might be it but being on the same one hand the same issues.
    Last edited by TysonLPrice; Jun 25th, 2015 at 05:44 AM.
    Please remember next time...elections matter!

  15. #15
    Hyperactive Member
    Join Date
    Oct 2013
    Posts
    389

    Re: How to pass values into a running program?

    If you want something that works out of the box, you may use one of my personal simplest methods that does this very elegantly,
    by sending input between two applications using PostMessage to a text field, who's handle is sent as a parameter to any application wishing to interact with my form.

    if this was Chinese to you check this quick source i wrote here -Attachment Removed by Moderator-

    Extract - compile both projects to the same folder - run Project1.exe click buttons on project2's form.



    Of course once you get the hang of things, it may be more elegant to fetch the handles via APIs (FindWindow, FindWindowEx) and such, maybe even use hooks on the post_message and instead of sending it to a textbox, send it straight to the form and process it from there, the possibilities are endless.

    but the principal is the same.
    Last edited by dday9; Jun 26th, 2015 at 09:07 AM.

  16. #16
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: How to pass values into a running program?

    Quote Originally Posted by TysonLPrice View Post
    I was very interested in seeing this work ( app in post #8) but it doesn't seem to for me. At least the way I imaged it would. "Click on App1 Command1' does not appear to work nor does "Click on App1 Command2'. I expected App1 to display "Left command button clicked" and so on. Sending text doesn't appear to work either. I'm on Windows 7 Professional.

    One last "anomaly" is clicking App2 "copy picture to App1 Picture1" put the picture in the upper left hand corner of my screen, not on the app.

    I was hoping it just worked "out of the box" to show to someone else I thought would be interested. I don't have time to try and debug it myself, at least in the near future.

    Edit:

    I had the apps split across two monitors and thought that might be it but being on the same one hand the same issues.
    I do not know if it will work on Windows 7. It works on XP.

    The first thing you have to do is to get the handles of App1's objects so you click on 'Get Objects From App1' button. That's it. You should now see the handle numbers of App1's objects in the left view area on App2. Now when you click on the other buttons everything works as it is expected. Make sure App1 is running before you click any buttons on App2 or you will get invalid handle numbers.

    I guess if I had given it a little more thought I would have put the 'Get Objects From App1' button code in the Form_Load event. I just thought everyone would know to click that button first. My bad here.

    Sorry I don't write perfect code
    Last edited by jmsrickland; Jun 25th, 2015 at 10:26 AM.


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  17. #17
    Wall Poster TysonLPrice's Avatar
    Join Date
    Sep 2002
    Location
    Columbus, Ohio
    Posts
    3,969

    Re: How to pass values into a running program?

    I'll try this at home but running if at work is generating missing valid digital signature errors and I start it. Thanks for posting.
    Please remember next time...elections matter!

  18. #18
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How to pass values into a running program?

    Quote Originally Posted by jmsrickland View Post
    That's basically the same thing posted in #8
    Yeah, I know. I just thought the OP might be interested in seeing a description of how that simple technique works, hence my link to penagate's short article about it.

    Quote Originally Posted by stum View Post
    ... but the principal is the same.
    Yep, posting a WM_CHAR message to a TextBox is doing essentially the same thing as sending a WM_SETTEXT message, which jmsrickland's and penagate's examples were demonstrating. One major difference though, is that the WM_CHAR message is limited to only 1 character code per message while the WM_SETTEXT message can carry far more information.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  19. #19
    Wall Poster TysonLPrice's Avatar
    Join Date
    Sep 2002
    Location
    Columbus, Ohio
    Posts
    3,969

    Re: How to pass values into a running program?

    Quote Originally Posted by jmsrickland View Post
    I do not know if it will work on Windows 7. It works on XP.

    The first thing you have to do is to get the handles of App1's objects so you click on 'Get Objects From App1' button. That's it. You should now see the handle numbers of App1's objects in the left view area on App2. Now when you click on the other buttons everything works as it is expected. Make sure App1 is running before you click any buttons on App2 or you will get invalid handle numbers.

    I guess if I had given it a little more thought I would have put the 'Get Objects From App1' button code in the Form_Load event. I just thought everyone would know to click that button first. My bad here.

    Sorry I don't write perfect code
    I wish I had just a very small fraction of your skill set
    Please remember next time...elections matter!

  20. #20
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,371

    Re: How to pass values into a running program?

    @stum - I removed you attachment from post 15 as it contained an EXE. Please read the rules regarding attachments here: http://www.vbforums.com/showthread.p...ts-Please-Read
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  21. #21

    Thread Starter
    Frenzied Member MrGTI's Avatar
    Join Date
    Oct 2000
    Location
    Ontario, Canada
    Posts
    1,277

    Resolved Re: How to pass values into a running program?

    I have been reviewing everything, and there is more than enough to keep me busy. I am sure I can use one of these methods. Thanks.

    I will mark the thread as resolved, but feel free to continue posting if you have something to add.
    ~Peter


Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width