Announcement

Collapse
No announcement yet.

Registrieren von einem DCOM-Server über die Applikation

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Registrieren von einem DCOM-Server über die Applikation

    habe einen DCOM Server und zugehörige Clients implementiert ..
    Funktioniert an sich ganz gut.
    Doch damit der Client mit dem Server redet muss er erst registriert werden..
    Es ist mir klar, dass es über die Eingabeaufforderung geht
    "TRegsvr -t Servername_tlb.pas"
    Doch ich kann es nicht den Nutzern zumuten diesen Befehl manuell auszuführen, deswegen suche ich nach einer Lösung, wie ich den Server über die Applikation selber registrieren kann..

  • #2
    Hallo,

    diese Aufgabe ist überhaupt kein Problem, da Borland den Sourcecode von TRegSrv zusammen mit Delphi ausliefert. Das folgende Beispiel erwartet, dass die TLB-Datei im gleichen Verzeichnis wie die ausführbare Programmdatei des Clients vorgefunden wird:
    <pre>
    <b>procedure</b> AppRegisterTLB(<b>const</b> sAppEXEName: <b>String</b>);
    <b>var</b>
    sPath: <b>string</b>;
    <br>
    <b>procedure</b> DoRegisterTLB(<b>const</b> sFilePath, sTlbName: <b>String</b>);
    <b>var</b>
    WFileName, DocName: WideString;
    TypeLib: ITypeLib;
    LibAttr: PTLibAttr;
    <b>resourcestring</b>
    SFileNotFound = <font color="#9933CC">'Datei &quot;%s&quot; konnte nicht gefunden werden!'</font>;
    <b>begin</b>
    WFileName := sFilePath + sTlbName;
    <b>if</b> <b>not</b> FileExists(WFileName) <b>then</b>
    <b>raise</b> Exception.CreateFmt(SFileNotFound, [WFileName]);
    OleCheck(LoadTypeLib(PWideChar(WFileName), TypeLib));
    OleCheck(TypeLib.GetLibAttr(LibAttr));
    <b>try</b>
    OleCheck(TypeLib.GetDocumentation(-1, <b>nil</b>, <b>nil</b>, <b>nil</b>, @DocName));
    DocName := ExtractFilePath(DocName);
    OleCheck(RegisterTypeLib(TypeLib, PWideChar(WFileName), PWideChar(DocName)));
    <b>finally</b>
    TypeLib.ReleaseTLibAttr(LibAttr);
    <b>end</b>;
    <b>end</b>;
    <br>
    <b>resourcestring</b>
    cTLBNAME1 = <font color="#9933CC">'COMObj.tlb'</font>;
    cPAN = <font color="#9933CC">'Die Typbibliothek wurde registriert.'</font>;
    cERR = <font color="#9933CC">'DCOM mit früher Bindung steht nicht zur Verfügung.'</font>;
    <b>begin</b>
    <b>try</b>
    sPath := ExtractFilePath(sAppEXEName);
    DoRegisterTLB(sPath, cTLBNAME1);
    ShowMessage(cPAN);
    <b>except</b>
    <b>on</b> E: Exception <b>do</b>
    <b>Raise</b> Exception.Create(E.Message + #10#13 + cERR);
    <b>end</b>;
    <b>end</b>;
    </pre>
    Der Client prüft dann beim Start nach, ob ein vereinbarter Schalter (Bsp: /R) übergeben wurde:
    <pre>
    <b>procedure</b> TFormMain.FormCreate(Sender: TObject);
    <b>begin</b>
    FIsConnected := False;
    <font color="#003399"><i>// Typbibliothek des COM+ Objekts auf dem Client-Rechner registrieren</i></font>
    <b>if</b> (ParamCount = 1) <b>and</b> (AnsiCompareText(ParamStr(1),<font color="#9933CC">'/R'</font>) = 0) <b>then</b>
    AppRegisterTLB(Application.EXEName);
    ...
    </pre>
    Beim Installationsprogramm aktiviert man die Option, dass die Anwendung am Ende gleich gestartet wird, wobei dort der Schalter /R übergeben wird. Somit registriert sich die TLB bei der Installation automatisch, wobei das auch funktioniert, wenn nur die EXE ausgetauscht und dann mit dem Schalter gestartet wird

    Comment


    • #3
      Vielen Dank für die schnelle Antwort!!

      Es klappt an sich wunderbar, doch eine Kleinigkeit stört mich noch..

      Bei der Auslieferung muss ich die *.tlb-Datei mitgeben. Bisher gab es nur die EXE mit. Gibt es dafür noch eine Lösung ?

      Ein Weiteres Problem habe ich dennoch. Die Clients laufen unter verschiedenen Accounts. Der Server unter einem bestimmten. Ich habe lange Zeit Probleme mit dem Callback gehabt, bis ich unter dem Reiter "COM-Standartsicherheit" den entprechenden Server hinzugefügt habe. Dieser Wert wird bei den Clients auch eingetragen werden müssen..
      Gibt es dafür einen Trick, wie man es über die Applikation macht? Z.B. durch einen Zugriff auf die Registry und den Eintrag bestimmter Werte.

      Comment


      • #4
        Hallo,

        &gt;..COM-Standardsicherheit...

        aus Sicherheitsgründen ist das keine gute Idee, aktuelle Win32-Versionen (ServicePacks) reagieren darauf mit dem Abschalten einiger Subsysteme (damit das Sicherheitsloch nicht zu groß wird).

        Statt dessen muss das Programm die verwendeten Interfaces separat freischalten. Die Suche nach der Zeichenkette <b>CoSetProxyBlanket</B> liefert hier im FORUM einige Beispiele zurück.

        &gt;... TLB in EXE...

        Siehe <i><a href="/webx?50@@.2cb7da43/4">Knut Lambert "TLB-files in resource files einbinden" 09.01.2004 06:53</a></i&gt

        Comment


        • #5
          Habe versucht die Security für die Applikation mit Hilfe der Funktion CoInitializeSecurity zu ändern:

          <PRE>
          const
          // Platform SDK: RPC_C_AUTHN_LEVEL_xxx
          RPC_C_AUTHN_LEVEL_DEFAULT = 0;
          RPC_C_AUTHN_LEVEL_NONE = 1; // Performs no authentication
          RPC_C_AUTHN_LEVEL_CONNECT = 2;
          RPC_C_AUTHN_LEVEL_CALL = 3;
          // Platform SDK: RPC_C_IMP_LEVEL_xxx
          RPC_C_IMP_LEVEL_DEFAULT = 0;
          RPC_C_IMP_LEVEL_ANONYMOUS = 1; // (Not supported in this release.)
          RPC_C_IMP_LEVEL_IDENTIFY = 2;
          EOAC_NONE = 0; begin
          CoInitialize(nil);
          CoInitializeSecurity(nil, -1, nil, nil,
          RPC_C_AUTHN_LEVEL_NONE,
          RPC_C_IMP_LEVEL_ANONYMOUS,
          nil, EOAC_NONE, nil);
          Application.Initialize;
          Application.CreateForm(TForm1, Form1);
          Application.Run;
          end.
          </PRE>

          Leider hat es nichts gebracht. Setze ich die beiden Standarteigenschaften manuell runter (Kein, Anonym) klappt es ..
          Woran mag das wohl liegen

          Comment


          • #6
            Ich merke schon, dass die ganze Angelegenheit doch nicht so einfach ist .. :-)
            Hoffe dennoch auf Hilfe ..

            In dem Beitrag drüber habe habe ich manuell die Standartsicherheit auf der Clientseite geändert. Welche Werte werden von dem Aufruf von CoInitializeSecurity beeinflusst? Wahrscheinlich nicht die Einstellungen für alle DCOM-Objekte..

            Muss ich evtl. etwas auf der Serverseite anders einstellen, oder vielleicht auch diese Funktion im Initialisierungsabschnitt von dem Server implementieren ??

            hmm.. Hoffe, dass jemand das noch verstehen kann .. :

            Comment


            • #7
              Hallo,

              der Aufruf von <i>CoSetProxyBlanket</i> funktionert auch dann zuverlässig, wenn aktuelle ServicePacks/Patches installiert sind. Da beide Seiten (Server und Client) nach dem "Wasserstands-Prinzip" die Minimal-Sicherheitsregeln für DCOM festlegen (d.h. beide Seiten verwendetn in jedem Fall den höchsten vorgefundenen Wert), muss auch der Server entsprechend vorbereitet werden

              Comment


              • #8
                Hallo..
                so wie ich das verstehe, kann ich die Sicherheit für die ganze Applikation mit CoInitializeSecurity und für das eine Interface mit CoSetProxyBlanket setzen.
                Da ich hier nur das eine Server-Interface im Client benutze ist es im Prinzip egal, welche Windows-Api-Funktion aufgerufen wird.

                Ich habe den oben beschriebenen Quellcode in beiden Applikationen implementiert (Server und Client) und trotzdem bekomme ich eine "Zugriff verweigert"-Fehlermeldung bei einem Callback .. (

                Habe ich was anderes vergessen ?
                Grüß

                Comment


                • #9
                  Wenn ich die Anwendungen lokal starte (auf einem Rechner), nachdem ich den Server auch mit CoInitializeSecurity starte, bekomme ich ebenso ein "Zugriff-Verweigert" ...

                  Lasse ich es hingegen weg, kann ich wenigstens lokal die Callbacks an die clients feuern..

                  Also irgendwie ergibt das ganze keinen Sinn.. :

                  Comment


                  • #10
                    Hallo,

                    &gt;..nachdem ich den Server auch mit CoInitializeSecurity starte, <br>
                    &gt;bekomme ich ebenso ein "Zugriff-Verweigert" ... <br>
                    &gt;..<br>
                    &gt;Also irgendwie ergibt das ganze keinen Sinn...

                    das sind eben die "Nebenwirkungen" der Sicherheitsregeln, die Microsoft nach jeder erfolgreichen Wurm/Virus-Attacke immer mehr verschärft (siehe meine Antwort vom 18.05.2004, 12:10 Uhr). Nach der neuen "offiziellen Lesart" sind XML Web Services für die Einsatzfälle vorgesehen, bei denen die DCOM-Sicherheit nicht benötigt wird <b>und</b> bei denen die beteiligten Rechner <b>nicht</b> von einem gemeinsamen Active Directory kontrolliert werden.

                    Da in Abhängigkeit von der Rechnerumgebung (Windows NT-Domäne, Active Directory im gemischen/nativen Modus, Policy- und Privilegien-Konfiguration) eine Fehlersuche aufgrund der zahlreichen Konfigurations-Alternativen mühsam ist, würde ich zur Eingrenzung des Problems mit dem einfachsten Fall anfangen:

                    1. Windows 2000 Server und Windows 2000 Professional-Client wurden auf Testrechner frisch installiert sind im gleichen neu eingerichteten Active Directory (dessen Default-Konfiguration nicht geändert wurde).

                    2. Die Standardsicherheits-Einstellung werden auf beiden Rechnern <b>nicht</b> geändert (also weder CoInitializeSecurity noch CoSetProxyBlanket aufrufen!).

                    3. Die DCOM-Konfiguration auf der Client-Seite muss dem Server-Konto den Aufruf des Clients (beim Callback ist der "Client" der DCOM-Server) erlauben.

                    Wenn das funktioniert, kann man dann schrittweise die Konfiguration von diesem Idealfall abweichen lassen. Sobald die Fehlermeldung erscheint, hat man die Ursache für die Probleme gefunden. Dann haben wir immer noch die Möglichkeit, auszuprobieren, ob die Hacks (CoInitializeSecurity / CoSetProxyBlanket) an dieser Stelle weiterhelfen.

                    Comment


                    • #11
                      Der Server-Rechner wurde neu installiert. Es sind dort also Standarteinstellungen vorhanden.
                      Habe die Einstellungen auf dem Client entsprechend geändert. CoInitializeSecurity / CoSetProxyBlanket sind, sowhol auf dem Server, als auch auf dem Client, weg.

                      Auf dem Server wurde unter den Einstellungen für das ServerObjekt die Zugangsberechtigung für den Clientrechner hinzugefügt (sonst kann die Serverinstanz nicht erzeugt werden)

                      Bei dieser Konstellation wird für die Clients die berechtigt sind eine Serverinstanz erzeugt. Das Anmelden klappt.. Wunderbar .. Sobald ein Callback kommt => "Zugriff verweigert"

                      Habe dann manuell auf der Clientseite unter "Standartzugriffsberechtigung" den ServerRechner hinzugefügt dann klappt es auch mit dem Callback..

                      Sonst habe ich es bisher nicht hinbekommen, dass der Callback ausgeführt wird.. Ob ich dann die Windows-Api-Funktionen ausführe, oder nicht .. Es ändert sich leider nichts ..
                      (((

                      Comment

                      Working...
                      X