Programm nur eine Instanz, aber wie ProgramParam. übergeben?
Programm nur eine Instanz, aber wie ProgramParam. übergeben?
Tachchen,
Wie ich mein programm in nur einer Instanz starten lassen kann habe ich bereits gefunden:
Programm - nur eine Instanz erlauben
Aber wir kann ich nun zB die Programmparameter die das zwete gestartete Programm bekommt, dann an das erste senden bevor ich das zweite dann wieder schließe ?
Also wenn ich zB eine Datei anklicke, und den Pfad nun an das erste gestartete Programm übergeben will?
Und vorallem wie "merkt" das erste programm das dann ?
Globaler Speicher ? Event ?
Bitte um Hilfe, danke im voraus.
Wie ich mein programm in nur einer Instanz starten lassen kann habe ich bereits gefunden:
Programm - nur eine Instanz erlauben
Aber wir kann ich nun zB die Programmparameter die das zwete gestartete Programm bekommt, dann an das erste senden bevor ich das zweite dann wieder schließe ?
Also wenn ich zB eine Datei anklicke, und den Pfad nun an das erste gestartete Programm übergeben will?
Und vorallem wie "merkt" das erste programm das dann ?
Globaler Speicher ? Event ?
Bitte um Hilfe, danke im voraus.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Programm nur eine Instanz, aber wie ProgramParam. überge
Code: Alles auswählen
Procedure OnlyOne(MutexName.s)
Protected *mem, i, count, para.s, tmp.s, hWnd, hWnd2
Protected cd.COPYDATASTRUCT
Protected result = CreateMutex_(0, 0, @MutexName)
If GetLastError_() = #ERROR_ALREADY_EXISTS
ReleaseMutex_(result)
CloseHandle_(result)
*mem = OpenSharedMemory("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx}")
hWnd = PeekI(*mem)
CloseSharedMemory(*mem)
If IsIconic_(hWnd)
ShowWindow_(hWnd, #SW_RESTORE)
EndIf
SetForegroundWindow_(hWnd)
count = CountProgramParameters()
For i = 1 To count
tmp = ProgramParameter(i - 1)
If FileSize(tmp) > 0
para + tmp + ";"
EndIf
Next
If para
cd\cbData = StringByteLength(para) + SizeOf(Character)
cd\lpData = @para
hWnd2 = OpenWindow(#PB_Any, 0, 0, 0, 0, "", #PB_Window_Invisible)
SendMessage_(hWnd, #WM_COPYDATA, hWnd2, cd)
While WindowEvent() : Wend
EndIf
End
EndIf
Prefs("SharedMemory") = Str(CreateSharedMemory("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx}", SizeOf(Integer)))
ProcedureReturn result
EndProcedure
Für Mutex und SharedMemory benutze ich dieselbe GUID. SharedMemory enthält nur das
hWnd des ersten Fensters, kann man also auch anders lösen.
Wenn erste Instance also existiert, dann setze ich es in den Fordergrund, weil das würde ja
auch passieren, wenn ich die zweite Instanz zulassen würde.
Danach lese ich die Parameter ein, in einen String und übermittle diese per WM_COPYDATA,
wo die erste Instanz dies dann im Callback mitbekommt und bearbeitet.
Falls ich doch der erste bin, wird dann der SharedMemory erstellt, in dem ich nach erstellen
des Fensters den hWnd poke.
Ich hoffe Du kommst damit so klar.
Gruß
Thomas
//edit:
Hier noch der entsprechende Ausschnitt aus dem Callback:
Code: Alles auswählen
Procedure WIN_MAIN_CB(hWnd, Msg, wParam, lParam)
Protected *cd.COPYDATASTRUCT
Protected para.s, i, count, tmp.s
Protected Result
Result = #PB_ProcessPureBasicEvents
Select Msg
Case #WM_COPYDATA
*cd = lParam
para = PeekS(*cd\lpData)
count = CountString(para, ";")
For i = 1 To count
tmp = StringField(para, i, ";")
Edit_New(tmp)
Next
ProcedureReturn Result
EndProcedure
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Re: Programm nur eine Instanz, aber wie ProgramParam. überge
Danke schon mal,
aus welcher Quelle nimmst du SharedMemory() befehle ?
Im Forum scheint nichts aktuelles zu sein ...
UNd das mit dieser GUID "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx}" ist doch frei ausgedacht oder ? ich kann doch genausogut einen "normalen" Namen für den Memory nutzen oder ?
aus welcher Quelle nimmst du SharedMemory() befehle ?
Im Forum scheint nichts aktuelles zu sein ...
UNd das mit dieser GUID "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx}" ist doch frei ausgedacht oder ? ich kann doch genausogut einen "normalen" Namen für den Memory nutzen oder ?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Re: Programm nur eine Instanz, aber wie ProgramParam. überge
@STARGÅTE
Wenn man nach "OpenSharedMemory" sucht, dann findet man zwei Threads von ts-soft und seine Codes/Includes funktionieren auch. Oder bekommst du irgendwelche Fehler?
Wenn man nach "OpenSharedMemory" sucht, dann findet man zwei Threads von ts-soft und seine Codes/Includes funktionieren auch. Oder bekommst du irgendwelche Fehler?
Ja kannst du auch machen. (Laut Beispiel von ts-soft in einem anderen Thread)STARGÅTE hat geschrieben:UNd das mit dieser GUID "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx}" ist doch frei ausgedacht oder ? ich kann doch genausogut einen "normalen" Namen für den Memory nutzen oder ?
Re: Programm nur eine Instanz, aber wie ProgramParam. überge
Nachdem ich die Namen umgeändert habe nicht mehr
Ich dachte ja er hat auf http://www.realsource.de/ irgendwo etwas ^^

Ich dachte ja er hat auf http://www.realsource.de/ irgendwo etwas ^^
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Programm nur eine Instanz, aber wie ProgramParam. überge
shared memory:
MakeGUID:
PS: ich würde immer eine GUID für solche Dinge verwenden, nur so kann man sicher sein, der Name ist einmalig!
Code: Alles auswählen
Define HandleMap
Procedure CreateSharedMemory(Name.s, Size)
Shared HandleMap
HandleMap = CreateFileMapping_(#INVALID_HANDLE_VALUE, 0, #PAGE_READWRITE|#SEC_COMMIT|#SEC_NOCACHE, 0, Size, @Name)
If HandleMap
ProcedureReturn MapViewOfFile_(HandleMap, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
EndIf
EndProcedure
Procedure OpenSharedMemory(Name.s)
Shared HandleMap
HandleMap = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, @Name)
If HandleMap
ProcedureReturn MapViewOfFile_(HandleMap, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
EndIf
EndProcedure
Procedure CloseSharedMemory(MemoryAddress)
Shared HandleMap
UnmapViewOfFile_(MemoryAddress)
CloseHandle_(HandleMap)
EndProcedure
Code: Alles auswählen
CompilerIf Defined(GUID, #PB_Structure) = #False
Structure GUID
Data1.l
Data2.w
Data3.w
Data4.b[8]
EndStructure
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
; requires uuid-dev
ImportC "-luuid"
uuid_generate(*out.GUID)
uuid_unparse_upper(*uu.GUID, *out)
EndImport
CompilerEndIf
Procedure.s MakeGUID()
Protected guid.GUID, result.s
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
result = Space(36)
uuid_generate(@guid)
uuid_unparse_upper(@guid, @result)
result = "{" + PeekS(@result, -1, #PB_Ascii) + "}"
CompilerCase #PB_OS_Windows
Protected lpsz.s{76}
If CoCreateGuid_(@guid) = #S_OK
result = PeekS(@lpsz, StringFromGUID2_(guid, @lpsz, 76), #PB_Unicode)
EndIf
CompilerDefault
CompilerEndSelect
ProcedureReturn result
EndProcedure
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Re: Programm nur eine Instanz, aber wie ProgramParam. überge
Danke, werde mir mal alles genauer angucken.
Noch eine Frage zu SharedMemory:
Du verwendest da ein HandleMap für "alle", heißt das, ich kann nur ein SharedMemory nutzen ?
DEnn wenn ich zB zwei erstelen würde, würde ja der zweite den ersten HandleMap überschreiben.
Beim schließen würde er dann immer nur den 2. schießen, weil der erste verloren gegangen ist, in bezug auf CloseHandle_()
Noch eine Frage zu SharedMemory:
Du verwendest da ein HandleMap für "alle", heißt das, ich kann nur ein SharedMemory nutzen ?
DEnn wenn ich zB zwei erstelen würde, würde ja der zweite den ersten HandleMap überschreiben.
Beim schließen würde er dann immer nur den 2. schießen, weil der erste verloren gegangen ist, in bezug auf CloseHandle_()
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Programm nur eine Instanz, aber wie ProgramParam. überge
HandleMap wird doch nur intern verwandt, ist also kein Rückgabewert, mit dem Du arbeiten mußtSTARGÅTE hat geschrieben:Noch eine Frage zu SharedMemory:
Du verwendest da ein HandleMap für "alle", heißt das, ich kann nur ein SharedMemory nutzen ?

Du kannst soviele Maps anlegen, wie virtueller Speicher erreichbar ist. Für Dein Vorhaben aber nicht
so sinnvoll, weil es ja keine Events gibts. Deshalb ja auch WM_COPYDATA.
Die Map wird erst mit dem schliessen der letzten Instance komplett geschlossen, wie beim laden von DLLs.
//edit
Die CloseFunktion solltest Du für mehrere Maps aber noch abändern. Letzte Zeile entfernen, handle wird
mit schliessen des Fensters automatisch freigegeben, genauso wie das Handle für den Mutex.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Re: Programm nur eine Instanz, aber wie ProgramParam. überge
Nach langem rumprobieren, scheint bei mir irgendwie das "CopyData" nicht zu funktionieren.
Hier mal ein reduzierter Code:
Es kommt einfach nix an (also kein "COPYDATA")
Wenn ich stattdessen #WM_CLOSE senden, wird es auch wirklich geschlossen ...
was mach ich falsch ?
Hier mal ein reduzierter Code:
Code: Alles auswählen
Text.s = "Hallo"
CopyData.COPYDATASTRUCT
CopyData\cbData = StringByteLength(Text) + SizeOf(Character)
CopyData\lpData = @Text
OpenWindow(1,100,100,100,100,"1")
OpenWindow(2,300,100,100,100,"2")
SendMessage_(WindowID(2), #WM_COPYDATA, WindowID(1), @CopyData)
;SendMessage_(WindowID(2), #WM_CLOSE, 0, 0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
CloseWindow(EventWindow())
Case #WM_COPYDATA
Debug "COPYDATA"
EndSelect
Until #False
Wenn ich stattdessen #WM_CLOSE senden, wird es auch wirklich geschlossen ...
was mach ich falsch ?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Programm nur eine Instanz, aber wie ProgramParam. überge
Was meinst Du, warum ich das Callback als Beispiel gepostet habe?
Im PB eventloop kommt ja leider nicht allzuviel an.

Im PB eventloop kommt ja leider nicht allzuviel an.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
