How do I share variable data between 2 VB programs ?
One is running as a service (using NtSvc.ocx) and since it does not use the LocalSystem account it can't interact with the Desktop.
I'm trying to write another app that will communicate with it and serve as it's GUI, just haven't found how to share the share data between them. DDE does not work, using sockets and TCP/IP works but not very well with large strings.
Thanks in advance.
Cakkie
October 12th, 2001, 01:34 AM
I see two more possibilities,
1) the first is COM, if you manage to create a COM interface for your service (so it actually is an Activex Exe), you could use the methods you expose to comunicate. This however will probabkly require you to redevelop most of the application, but is by far the most reliable way.
2) Files. You can comunicate using files. Say you have a client and a server (the service in this case). Let the service look at the data in a file (like say c:\SERVICE-IN.TXT), and let the client look at the data in another file (like say c:\CLIENT-IN.TXT). Both programs need to write to the others IN file, resulting in a way to comunicate. This might not be a clean solution, but it is probably one of the easiest to implement.
Tom Cannaerts
slisse@planetinternet.be
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning -- Rich Cook
Clearcode
October 12th, 2001, 03:14 AM
You could use RegisterWindowMessage() API to create a new message and send it to your GUI app using the SendMessage() API?
HTH,
D.
-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com
Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.
alvarezr
October 15th, 2001, 12:31 PM
I though Activex EXEs can only be initiated by the client APP. Since my server APP needs to run as a service it has to be able to start on its own, but somehow sharing it's data. Right now I'm using SocketWrench from Catalyst to comunicate both APPs via TCP/IP, but what I really want to do is share the variable data in a more elegant way.
alvarezr
October 15th, 2001, 12:34 PM
This is a good suggestion, where can I find examples on how to do it ?
What I really need, though, is a way to have a single shared data area where mutiple apps can see and/or change the variable values.
Clearcode
October 16th, 2001, 08:19 AM
In order to pass memory between threads it must be global memory.
'\\ Global memory management functions
private Declare Function GlobalLock Lib "kernel32" (byval hMem as Long) as Long
private Declare Function GlobalSize Lib "kernel32" (byval hMem as Long) as Long
private Declare Function GlobalUnlock Lib "kernel32" (byval hMem as Long) as Long
private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest as Any, lpvSource as Any, byval cbCopy as Long)
private Declare Function GlobalAlloc Lib "kernel32" (byval wFlags as Long, byval dwBytes as Long) as Long
private Declare Function GlobalFree Lib "kernel32" (byval hMem as Long) as Long
private mMyData() as Byte
private mMyDataSize as Long
private mHmem as Long
public Enum enGlobalmemoryAllocationConstants
GMEM_FIXED = &H0
GMEM_DISCARDABLE = &H100
GMEM_MOVEABLE = &H2
GMEM_NOCOMPACT = &H10
GMEM_NODISCARD = &H20
GMEM_ZEROINIT = &H40
End Enum
'**************************************
' Name: Global memory
' Description:Allows you to read and wri
' te global memory blocks, which in turn a
' llows you to pass big chunks of data bet
' ween applications easily.
' By: Duncan Jones
'
'
' Inputs:None
'
'\\ --[CopyFromHandle]---------------------------
'\\ Copies the data from a global memory handle
'\\ to a private byte array copy
'\\ ---------------------------------------------
public Sub CopyFromHandle(byval hMemHandle as Long)
Dim lRet as Long
Dim lPtr as Long
lRet = GlobalSize(hMemHandle)
If lRet > 0 then
mMyDataSize = lRet
lPtr = GlobalLock(hMemHandle)
If lPtr > 0 then
ReDim mMyData(0 to mMyDataSize - 1) as Byte
CopyMemory mMyData(0), byval lPtr, mMyDataSize
Call GlobalUnlock(hMemHandle)
End If
End If
End Sub
'\\ --[CopyToHandle]-----------------------------
'\\ Copies the private data to a memory handle
'\\ passed in
'\\ ---------------------------------------------
public Sub CopyToHandle(byval hMemHandle as Long)
Dim lSize as Long
Dim lPtr as Long
'\\ Don't copy if its empty
If Not (mMyDataSize = 0) then
lSize = GlobalSize(hMemHandle)
'\\ Don't attempt to copy if zero size..
If lSize > 0 then
lPtr = GlobalLock(hMemHandle)
If lPtr > 0 then
CopyMemory byval lPtr, mMyData(0), lSize
Call GlobalUnlock(hMemHandle)
End If
End If
End If
End Sub
Of course, you still need to pass the global handles bewteen your applications and should probably implement some kind of MutEx protection to prevent one app writing memory that another is reading...
HTH,
Duncan
-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com
Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.
alvarezr
October 16th, 2001, 10:07 AM
This is great !!!, Thanks, Duncan.
Now, How do each app find each other in memory, so the data can be exchanged ??
I'm still thinking about the way it used to be in assembler, where all you had to do was pass the starting address of the memory block that contained the shared data (usually with an interrupt call), and from then on all symbolic variables in both apps referred to the exact same memory location. I guess in VB is a bit more convoluted (or is it because of Windows?).
Coco Loco
Clearcode
October 16th, 2001, 10:30 AM
One of the huge security advances in windows NT/9x over 3.1 is that in the new world order, evrey thread has its own local storage and to simplify slightly that storage is not visible outside of that thread. This is good because when threads (and therefore applications) are allowed to mess around with each other's memory then a GPF is never far behind.
However, you do sometimes need to pass bits of memory between applications - for instance if you use the clipboard. For this case you need to allocate some global memory in one application which will give you an unique Global Memory handle then copy your data to the memory thus allocated.
Then you need to inform the second application that memory is available and pass across that global memory handle and the recipient should then copy the data from that handle and then inform the first application that it has done so so that it may free up the allocated global memory.
There are a number of ways to pass the handle between two applications, but in my opinion the best way is using SendMessage.
First you need to register two new messages that you will use to communicate between your applications with the RegisterWindowsMessage() API call:
'Declarations:
Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (byval lpString as string) as Long
'Use
public Function MSG_NewDataAvailable() as Long
static wmsg as Long
If wmsg = 0 then
wmsg = RegisterWindowMessage("NEWGLOBALMEMORY")
End If
MSG_NewDataAvailable = wmsg
End Function
public Function MSG_AcknowledgeData() as Long
static wmsg as Long
If wmsg = 0 then
wmsg = RegisterWindowMessage("ACKNOWLEDGEGLOBALMEMORY")
End If
MSG_AcknowledgeData= wmsg
End Function
This code will need to be added in a common .bas module in both your applications...
-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com
Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.
Clearcode
October 16th, 2001, 10:42 AM
Then, in order to use this you need to subclass the WNDPROC of both your application's windows.
There are plenty of examples of subclassing - including http://www.MerrionComputing.com/OnlineIssue2.htm
In the WNDPROC:
'declarations...
private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (byval lpPrevWndFunc as Long, byval hwnd as Long, byval msg as Long, byval wParam as Long, byval lParam as Long) as Long
Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (byval hwnd as Long, byval wMsg as Long, byval wParam as Long, byval lParam as Long) as Long
'\\ --[VB_WindowProc]-------------------------------------------------------------------
'\\ 'typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
'\\ Parameters:
'\\ hwnd - window handle receiving message
'\\ wMsg - The window message (WM_..etc.)
'\\ wParam - First message parameter
'\\ lParam - Second message parameter
'\\ Note:
'\\ When subclassing a window proc using this, set the eventhandler's
'\\ hOldWndProc property to the window's previous window proc address.
'\\ ----------------------------------------------------------------------------------------
'\\ You have a royalty free right to use, reproduce, modify, publish and mess with this code
'\\ I'd like you to visit http://www.merrioncomputing.com for updates, but won't force you
'\\ ----------------------------------------------------------------------------------------
public Function VB_WindowProc(byval hwnd as Long, byval wMsg as Long, byval wParam as Long, byval lParam as Long) as Long
If wMsg = MSG_NewDataAvailable() then
'lParam is the memory handle,
'wParam is the window sending the message
'\\ Copy the meory from the handle..
'\\ Acknowledge that we got the memory
Call SendMessageLong(wParam,MSG_AcknowledgeGlobalMemory(), hwnd,lParam)
ElseIf wMsg = MSG_AcknowledgeGlobalMemory() then
'lParam is the memory handle,
'wParam is the window sending the message
'\\ Free the memory in lParam
else
VB_WindowProc = CallWindowproc(hOldProc, hWnd,lParam,wParam)
End If
End Function
The allocating and freeing of memory is as per the first post in this thread....
HTH,
Duncan
-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com
Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.
KaDuKa
August 11th, 2005, 09:49 AM
Sup!
I'am from Brazil but I'll try to write in English.
Could someone give us a complete code that works?
I am writing these examples in VB6 without success... :(
note: i don't need an example to pass the handle using sendmessage, i can do this givind the value from one executable and writing the exact value to another executable trought a textbox. I just need the code to write and load the memory because I am trying and trying...but didn't work yet
I am using windows xp sp2
thanks,
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.