Page 1 of 1
Run one instace but get command line?
Posted: Fri Jan 17, 2014 2:20 pm
by ricardo
Hi
I want to run only one instance o my app, but receives in that running instance any command line sent to the instances that does not open.
I mean i have have running myapp.exe and someone try to run myapp.exe again with this command line: /start, i want to be able to receive that command line in the instance that is runnig.
Any help are welcome.
Re: Run one instace but get command line?
Posted: Fri Jan 17, 2014 2:32 pm
by doctorized
If I were you I would create a thread to watch ProgramParameter().
Re: Run one instace but get command line?
Posted: Fri Jan 17, 2014 3:58 pm
by srod
Biggest problem is passing the program parameters from one instance to another as one instance does not have access to the command line passed to any other.
I would suggest looking at Psych's code below which allows you to prevent multiple instances running. His code uses a global file mapping object which is pretty neat. You should be able to modify it to actually send the program parameters (via the file mapping object) to the original instance. Just use RegisterWindowMessage_() to get a global message you can send. When the original instance receives this message (use a window callback) then it can simply open up the file mapping object itself and read the data.
The alternative is a global mutex object (Win API) and a combination of global messages and #WM_COPYDATA.
http://www.purebasic.fr/english/viewtop ... 12&t=47684
Re: Run one instace but get command line?
Posted: Fri Jan 17, 2014 5:22 pm
by JHPJHP
UPDATE:
- I found my original post:
http://www.purebasic.fr/english/viewtop ... 13&t=55720
It seems that srod's COMatePLUS may be a more viable solution to this approach... see post.
---------------------------
srod's approach (from Psych's code) is probably the way to go, but thinking out-loud...
I wrote some script awhile back to get the command line from a running process, similar to "Process Explorer", that may provide a solution?
I'm currently at work and don't have access to the code, but I'll post something when I'm home tonight... providing this has not been resolved, and a Windows only solution would suffice?
Re: Run one instace but get command line?
Posted: Fri Jan 17, 2014 7:27 pm
by uwekel
Re: Run one instace but get command line?
Posted: Fri Jan 17, 2014 9:16 pm
by ricardo
Can i use sendmessage? How ca i do it?
Re: Run one instace but get command line?
Posted: Fri Jan 17, 2014 9:28 pm
by netmaestro
This code doesn't assume your use of a window. If you do use a window, simply exchange the message-only window in the code with your own.
How to test: Copy the code into two new ide windows. In the first code window, go to Compiler Options->Compile/Run->Executable Commandline and enter this string:
/TEST1 /SAYCHEESE1. In the second code window, enter
/TEST2 /SAYCHEESE2 in the same place. Then run the first code (it will run 20 seconds) and while it's running, run the second code.
When you run the first code you should see this line in the debug window:
My parameter(s): /TEST1 /SAYCHEESE1
Your second code run should end immediately after you start it. When it does, a new line will appear in the first debug window:
My parameter(s): /TEST1 /SAYCHEESE1
Received parameter(s): /TEST2 /SAYCHEESE2
Code: Select all
Declare WinProc(hwnd, msg, wparam, lparam)
#STRING_MESSAGE = 2
#HWND_MESSAGE = -3
Lockstr$ = "a string of my choice"
; Place any and all program parameters in paramstr$
paramstr$ = ""
result=CountProgramParameters()
For i=0 To result-1
paramstr$+ProgramParameter(i)+" "
Next
; Check for instance already running, if found send paramstr$ and end
*MyMutex = CreateMutex_(#Null, 1, LockStr$)
If *MyMutex <> 0 And GetLastError_() = #ERROR_ALREADY_EXISTS
CloseHandle_(*MyMutex)
window = FindWindow_(0, "TESTING_WINDOW")
*stringdata.COPYDATASTRUCT = AllocateMemory(SizeOf(COPYDATASTRUCT))
With *stringdata
\dwData = #STRING_MESSAGE
\cbData = StringByteLength(paramstr$)+SizeOf(CHARACTER)
\lpData = @paramstr$
EndWith
SendMessage_(window, #WM_COPYDATA, #Null, *stringdata)
End
EndIf
Debug "My parameter(s): " + paramstr$
OpenWindow(0, 0, 0, 0, 0, "TESTING_WINDOW", #HWND_MESSAGE)
SetWindowCallback(@WinProc(), 0)
AddWindowTimer(0, 1, 15000)
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_Timer
End
EndSelect
Until EventID = #PB_Event_CloseWindow
;=========================================
; PROCEDURE SECTION
;=========================================
Procedure WinProc(hwnd, msg, wparam, lparam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_COPYDATA
*pp.COPYDATASTRUCT = lparam
Select *pp\dwData ; determine the type of data being sent and process accordingly
Case #STRING_MESSAGE
Debug "Received parameter(s): " + PeekS(*pp\lpData)
EndSelect
result = #True ; You should return #True if processing #WM_COPYDATA
EndSelect
ProcedureReturn result
EndProcedure