Controls per Code registrieren?

Nutzung, Komponenten, .NET

Moderator: Moderatoren

Antworten
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9358
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Controls per Code registrieren?

Beitrag von Tom »

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?
Herzlich,
Tom
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16508
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Controls per Code registrieren?

Beitrag von Martin Altmann »

Hallo Tom,
Tom hat geschrieben:... - was allerdings nicht immer klappt, vor allem nicht unter Vista.
selbstverständlich klappt das auch unter Vista - Du musst doch "nur" das regsvr32 als Administrator aufrufen!
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
:grommit:
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.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9358
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Controls per Code registrieren?

Beitrag von Tom »

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.
Herzlich,
Tom
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16508
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Controls per Code registrieren?

Beitrag von Martin Altmann »

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
:grommit:
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.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Controls per Code registrieren?

Beitrag von AUGE_OHR »

Martin Altmann hat geschrieben:auch dafür braucht man latürnich Adminrechte...
für Novell gab es ApRights womit man einem Programm die Adminrechte geben konnte.

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
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9358
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Controls per Code registrieren?

Beitrag von Tom »

Hallo, Jimmy.

Es ist auch möglich, "Request Admin Rights" in die Manifest-Datei einzubauen.
Herzlich,
Tom
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Controls per Code registrieren?

Beitrag von AUGE_OHR »

Tom hat geschrieben:Es ist auch möglich, "Request Admin Rights" in die Manifest-Datei einzubauen.
das habe ich noch nicht ausprobiert.

ich meinte das hier : http://www.xbwin.com/forum.php?ng=/ot4x ... leges.html
gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Controls per Code registrieren?

Beitrag von AUGE_OHR »

Tom hat geschrieben:Und die unsichere Frage lautet: Legt das Control immer die gleichen Keys an?
nicht sicher ob du "diese" Keys meinst

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
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Controls per Code registrieren?

Beitrag von AUGE_OHR »

hi,

... wofür ist C:\Programme\Codejock Software\ActiveX\Xtreme SuitePro ActiveX v13.0.0\Bin\Registrator.exe ?
gruss by OHR
Jimmy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9358
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Controls per Code registrieren?

Beitrag von Tom »

@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
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Re: Controls per Code registrieren?

Beitrag von Markus Walter »

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:

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 Ausfhrung (oder auf TimeOut) warten:
  lResult := WaitForSingleObject(hThread, nTimeOut)

  // Liefert WaitForSingleObject WAIT_OBJECT_0 zurck, war
  // die Abarbeitung vor Erreichen des TimeOuts erfolgreich:
  If lResult = WAIT_OBJECT_0
    // ExitCode des Threads ermitteln - bei Rckgabe von 0
    // hat die aufgerufene Funktion die Aktion erfolgreich
    // durchgefhrt:
    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
Antworten