Controls per Code registrieren?
Moderator: Moderatoren
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Controls per Code registrieren?
Wenn man (wie ich: gleich mehrere) Active-X-Controls mit der Applikation ausliefert, und sie sind noch nicht installiert, gibt es die Möglichkeit, REGSVR32 [MeinControl.OCX] per RunShell auszuführen - was allerdings nicht immer klappt, vor allem nicht unter Vista. Ärgerlich ist das, wenn die App dann nicht läuft, weil Bedienungselemente fehlen - zum Beispiel eine ShortCutBar aus Codejock oder ähnliches.
Die Registrierung eines Controls besteht meiner Kenntnis nach schlicht darin, dass diverse Registry-Schlüssel hinterlegt werden. Nun könnte man natürlich dahergehen, eine Sicherung der Reg anlegen, ein Control installieren und danach die beiden Reg-Versionen vergleichen. Die Erzeugung von Reg-Keys aus einer Applikation heraus gelingt ja weitgehend mühelos. Aber das scheint mir ein unsicherer und holpriger Weg zu sein, der außerdem eine haarige Fehlerquelle wäre. Und die unsichere Frage lautet: Legt das Control immer die gleichen Keys an?
Controls stellen die exportierte Funktion "DLLRegisterServer" zur Verfügung, über die sie sich dann selbst registrieren. Nur: Wie kommt man da ran? Ich habe noch keinen Weg gefunden, das aus Xbase++ heraus zu tun. Mit Delphi geht es übrigens.
Any ideas?
Die Registrierung eines Controls besteht meiner Kenntnis nach schlicht darin, dass diverse Registry-Schlüssel hinterlegt werden. Nun könnte man natürlich dahergehen, eine Sicherung der Reg anlegen, ein Control installieren und danach die beiden Reg-Versionen vergleichen. Die Erzeugung von Reg-Keys aus einer Applikation heraus gelingt ja weitgehend mühelos. Aber das scheint mir ein unsicherer und holpriger Weg zu sein, der außerdem eine haarige Fehlerquelle wäre. Und die unsichere Frage lautet: Legt das Control immer die gleichen Keys an?
Controls stellen die exportierte Funktion "DLLRegisterServer" zur Verfügung, über die sie sich dann selbst registrieren. Nur: Wie kommt man da ran? Ich habe noch keinen Weg gefunden, das aus Xbase++ heraus zu tun. Mit Delphi geht es übrigens.
Any ideas?
Herzlich,
Tom
Tom
- Martin Altmann
- Foren-Administrator
- Beiträge: 16555
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: Controls per Code registrieren?
Hallo Tom,
Dazu gibt es ja zusätzlich zum Befehl run das Kommando runas - dem kann man das alles mitgeben. Latürnich muß der Benutzer das aufpoppende Dialogfenster bestätigen.
Viele Grüße,
Martin
selbstverständlich klappt das auch unter Vista - Du musst doch "nur" das regsvr32 als Administrator aufrufen!Tom hat geschrieben:... - was allerdings nicht immer klappt, vor allem nicht unter Vista.
Dazu gibt es ja zusätzlich zum Befehl run das Kommando runas - dem kann man das alles mitgeben. Latürnich muß der Benutzer das aufpoppende Dialogfenster bestätigen.
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Controls per Code registrieren?
Hallo, Martin.
Klar kriegt man das hin. Aber wenn Du zwanzig Controls zu installieren hast (was wir natürlich problemlos aus der Installationsroutine heraus tun, aber viele Anwender schubsen die Applikation einfach von einem Arbeitsplatz auf den nächsten, ohne Installation), erscheinen zwanzig Erfolgsfensterchen von REGSVR32 - und unter Vista im Zweifelsfall nochmal so viele des UAC. Außerdem gibt es lustige Windows-Installationsvarianten, übereifrige Administratoren, die bestimmte EXEn aus den Windows-Verzeichnissen löschen, Administrationsrechte verbieten usw. usf. Man kann sich also nicht darauf verlassen, dass es klappt - und meiner Erfahrung nach ist es oft eben so, dass es tatsächlich nicht klappt. Deshalb wäre die Registrierung per Code viel eleganter. Es geht ja "nur" darum, ein paar Schlüssel zu hinterlegen. Oder, besser noch, die exportierte Funktion der Controls aufzurufen.
Klar kriegt man das hin. Aber wenn Du zwanzig Controls zu installieren hast (was wir natürlich problemlos aus der Installationsroutine heraus tun, aber viele Anwender schubsen die Applikation einfach von einem Arbeitsplatz auf den nächsten, ohne Installation), erscheinen zwanzig Erfolgsfensterchen von REGSVR32 - und unter Vista im Zweifelsfall nochmal so viele des UAC. Außerdem gibt es lustige Windows-Installationsvarianten, übereifrige Administratoren, die bestimmte EXEn aus den Windows-Verzeichnissen löschen, Administrationsrechte verbieten usw. usf. Man kann sich also nicht darauf verlassen, dass es klappt - und meiner Erfahrung nach ist es oft eben so, dass es tatsächlich nicht klappt. Deshalb wäre die Registrierung per Code viel eleganter. Es geht ja "nur" darum, ein paar Schlüssel zu hinterlegen. Oder, besser noch, die exportierte Funktion der Controls aufzurufen.
Herzlich,
Tom
Tom
- Martin Altmann
- Foren-Administrator
- Beiträge: 16555
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: Controls per Code registrieren?
Yup - volle Zustimmung!
Aber Dein nur ist latürnich das gleiche in Grün - auch dafür braucht man latürnich Adminrechte...
Viele Grüße,
Martin
Aber Dein nur ist latürnich das gleiche in Grün - auch dafür braucht man latürnich Adminrechte...
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Controls per Code registrieren?
für Novell gab es ApRights womit man einem Programm die Adminrechte geben konnte.Martin Altmann hat geschrieben:auch dafür braucht man latürnich Adminrechte...
Ich denke ich habe irgendwo einen DLLCall für Windows wo man ebenfalls einer Application die nötgen
Admin Rechte geben kann ... muss mal suchen gehen ...
gruss by OHR
Jimmy
Jimmy
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Controls per Code registrieren?
Hallo, Jimmy.
Es ist auch möglich, "Request Admin Rights" in die Manifest-Datei einzubauen.
Es ist auch möglich, "Request Admin Rights" in die Manifest-Datei einzubauen.
Herzlich,
Tom
Tom
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Controls per Code registrieren?
das habe ich noch nicht ausprobiert.Tom hat geschrieben:Es ist auch möglich, "Request Admin Rights" in die Manifest-Datei einzubauen.
ich meinte das hier : http://www.xbwin.com/forum.php?ng=/ot4x ... leges.html
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Controls per Code registrieren?
nicht sicher ob du "diese" Keys meinstTom hat geschrieben:Und die unsichere Frage lautet: Legt das Control immer die gleichen Keys an?
Code: Alles auswählen
FUNCTION HX_VERSION(cVersion)
LOCAL cOldVersion
//
// STATIC hold Version Number
//
STATIC scVersion
IF Empty(scVersion)
scVersion := GetEnv('CODEJOCK_VERSION')
IF Empty(scVersion)
scVersion := SearchOCX()
IF Empty(scVersion)
Msgbox("Envioment SET 'CODEJOCK_VERSION'= xx.x.x not set")
QUIT
ENDIF
ENDIF
ENDIF
cOldVersion := scVersion
IF PCount() > 0
scVersion := cVersion
ENDIF
RETURN '.' + cOldVersion
FUNCTION SearchOCX()
LOCAL lDemo := .F.
LOCAL lRelease := .F.
LOCAL aCJKeys
LOCAL aSubkeys
LOCAL oReg := ""
LOCAL nPosi := 0
LOCAL nLen := 0
LOCAL cRet := ""
LOCAL i, iMax,j
LOCAL aDir
LOCAL uVal
LOCAL aCJVer := {"Codejock.Calendar.Unicode.v",;
"Codejock.Calendar.v",;
"Codejock.CommandBars.Unicode.v",;
"Codejock.CommandBars.v",;
"Codejock.Controls.Unicode.v",;
"Codejock.Controls.v",;
"Codejock.DockingPane.Unicode.v",;
"Codejock.DockingPane.v",;
"Codejock.Markup.Unicode.v",;
"Codejock.Markup.v",;
"Codejock.PropertyGrid.Unicode.v",;
"Codejock.PropertyGrid.v",;
"Codejock.ReportControl.Unicode.v",;
"Codejock.ReportControl.v",;
"Codejock.ShortcutBar.Unicode.v",;
"Codejock.ShortcutBar.v",;
"Codejock.SkinFramework.Unicode.v",;
"Codejock.SkinFramework.v",;
"Codejock.SyntaxEdit.Unicode.v",;
"Codejock.SyntaxEdit.v",;
"Codejock.TaskPanel.Unicode.v",;
"Codejock.TaskPanel.v"}
oReg := XbpReg():NEW("HKEY_CURRENT_USER\Software\Codejock Software")
IF oReg:Status()
ELSE
MSGBOX("no Codejock Software installed ?")
RETURN cRet
ENDIF
aCJKeys := oReg:KeyList()
iMax := LEN(aCJKeys)
i := 1
FOR i := 1 TO iMax
oReg := XbpReg():NEW("HKEY_CURRENT_USER\Software\Codejock Software\"+aCJKeys[i])
IF oReg:Status()
IF "30 Day Trial" $ aCJKeys[i]
lDemo := .T.
ENDIF
aSubkeys := oReg:ValueList(.T.)
nLen := LEN(aSubkeys)
j := 1
FOR j := 1 TO nLen
IF "Installation Directory" $ aSubkeys[j][1]
uVal := aSubkeys[j][2]
aDir := Directory(uVal+"\Bin\*.ocx")
IF LEN(aDir) > 0
IF "30 Day Trial" $ uVal
lDemo := .T.
ELSE
lDemo := .F.
lRelease := .T.
ENDIF
nPosi := AT(" v",uVal)
IF nPosi > 0
cRet := ALLTRIM(SUBSTR(uVal,nPosi+2,LEN(uVal)-nPosi+2))
ENDIF
ENDIF
ENDIF
NEXT
ENDIF
NEXT
IF !EMPTY(cRet)
IF "30 Day Trial" $ cRet
cRet := StrTran( cRet,"30 Day Trial","")
ENDIF
Msgbox("your Envioment is not SET corecct,please use"+CRLF+;
"SET 'CODEJOCK_VERSION'="+cRet,"SET 'CODEJOCK_VERSION'")
ENDIF
RETURN cRet
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Controls per Code registrieren?
hi,
... wofür ist C:\Programme\Codejock Software\ActiveX\Xtreme SuitePro ActiveX v13.0.0\Bin\Registrator.exe ?
... wofür ist C:\Programme\Codejock Software\ActiveX\Xtreme SuitePro ActiveX v13.0.0\Bin\Registrator.exe ?
gruss by OHR
Jimmy
Jimmy
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Controls per Code registrieren?
@Jimmy: Das ist ein allgemeiner OCX-Registrator, den man für die Registrierung aller möglichen Komponenten nutzen kann. Als DLL gibt's das leider nicht.
Herzlich,
Tom
Tom
- Markus Walter
- Programmier-Gott
- Beiträge: 1018
- Registriert: Di, 24. Jan 2006 10:22
- Wohnort: Saarland
Re: Controls per Code registrieren?
Hallo Tom,
ich habe da was über api gefunden. regsrv32 ist dann nicht notwendig.
Habe den Code aus einem VB-Sample portiert. Für meine Anforderungen ist es geeignet:
ich habe da was über api gefunden. regsrv32 ist dann nicht notwendig.
Habe den Code aus einem VB-Sample portiert. Für meine Anforderungen ist es geeignet:
Code: Alles auswählen
#include "dll.ch"
#define WAIT_ABANDONED 0x80
#define WAIT_FAILED 0xFFFFFFFF
#define WAIT_OBJECT_0 0x0
#define WAIT_TIMEOUT 0x102
#define INFINITE 0xFFFF
DLLFUNCTION LoadLibraryA(cFileName) USING STDCALL from kernel32.dll
DLLFUNCTION FreeLibrary(hModule) USING STDCALL from kernel32.dll
DLLFUNCTION GetProcAddress(hModule, ProcedureName) USING STDCALL from kernel32.dll
DLLFUNCTION CreateThread(ThreadAttributes, nStackSize, nStartAddress, nParameter, nCreationFlags, nThreadID) USING STDCALL from kernel32.dll
DLLFUNCTION GetExitCodeThread(hThread, @nExitCode) USING STDCALL from kernel32.dll
DLLFUNCTION WaitForSingleObject(hObject, nTimeOut) USING STDCALL from kernel32.dll
DLLFUNCTION CloseHandle(hObject) USING STDCALL from kernel32.dll
function RegisterServer(cPathToFile, lRegister, nTimeOut)
* Registriert oder deregistriert eine ActiveX-DLL oder ein OCX
* --------------------------------------------------------------------------------
* Parameterinformation:
* --------------------------------------------------------------------------------
*
* - PathToFile: Vollst„ndiger Pfad zur Datei, die den COM-Server enth„lt.
*
* - Register: TRUE, um den COM-Server zu registrieren.
* (optional) FALSE, um den COM-Server zu deregistrieren.
* Standardwert: TRUE (Registrierung des COM-Servers)
*
* - TimeOut: Zeit in Millisekunden, die maximal auf den Vorgang
* (optional) verwendet werden soll. Im Regelfall gibt die Funktion
* sofort nach erledigter Registrierung/Deregistrierung
* oder nach erkannter Unmöglichkeit der Aktion die Ablauf-
* kontrolle an den Aufrufer zurück.
* Standardwert: 5000 (maximal 5 Sekunden)
*
* Rückgabewert: TRUE bei erfolgreicher Aktion, FALSE bei erfolgloser Aktion.
*
* --------------------------------------------------------------------------------
local hModule // Handle auf ein geladenes Modul
local lProcAddress // Adresse einer Funktion in einem geladenen Modul
local hThread // Handle auf einen Thread
local nThreadID // ID eines Threads
local lResult // Rückgabewert für WaitForSingleObject
local nExitCode := 0 // Exit-Code des erzeugten Threads
local lRet := .f.
if valtype(lRegister) # "L"
lRegister := .t.
endif
if valtype(nTimeOut) # "N"
nTimeOut := 5000
endif
// Versuchen, die angegebene Datei als Modul zu laden
hModule := LoadLibraryA(cPathToFile)
// Wenn kein Modul-Handle vorliegt, war LoadLibrary erfolglos:
If hModule == 0
return .f.
Endif
// Versuchen, die Adresse der Funktion DllRegisterServer (bzw.
// DllUnregisterServer) zu ermitteln:
lProcAddress := GetProcAddress(hModule, IIf(lRegister, "DllRegisterServer", "DllUnregisterServer"))
// Sofern Funktionsadresse = 0, war GetProcAddress erfolglos:
If lProcAddress == 0
FreeLibrary(hModule) // Bereits geladenes Modul freigeben
return .f.
Endif
// Versuchen, die Funktion aufzurufen:
hThread := CreateThread(NIL, 0, lProcAddress, 0, 0, nThreadID)
// Liegt kein Thread-Handle vor, war CreateThread erfolglos:
If hThread == 0
FreeLibrary(hModule) // Bereits geladenes Modul freigeben
return .f.
Endif
// Auf Abarbeitung der Ausfhrung (oder auf TimeOut) warten:
lResult := WaitForSingleObject(hThread, nTimeOut)
// Liefert WaitForSingleObject WAIT_OBJECT_0 zurck, war
// die Abarbeitung vor Erreichen des TimeOuts erfolgreich:
If lResult = WAIT_OBJECT_0
// ExitCode des Threads ermitteln - bei Rckgabe von 0
// hat die aufgerufene Funktion die Aktion erfolgreich
// durchgefhrt:
GetExitCodeThread(hThread, @nExitCode)
If nExitCode == 0
lRet := .t.
EndIf
EndIf
CloseHandle(hThread) // Handle auf den erzeugten Thread freigeben
FreeLibrary(hModule) // Geladenes Modul freigeben
return lRet
Gruß
Markus
Mitglied der XUG Saarland-Pfalz
Markus
Mitglied der XUG Saarland-Pfalz