AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

ADS - Fullname

Ein Thema von MarLe · begonnen am 24. Jan 2007 · letzter Beitrag vom 2. Feb 2007
Antwort Antwort
Seite 1 von 3  1 23      
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#1

ADS - Fullname

  Alt 24. Jan 2007, 13:32
Hallo,

Hab ein ADS Beispiel ADS-Info heruntergeladen (Ich glaub von dieser Anfrage)
http://www.delphipraxis.net/internal...ct.php?t=95077

Bräuchte jetzt noch eine Funktion um über ADS den Fullname zu bekommen.
Meine Funktion schmiert mir aber mit einer Exception ab!?!

Delphi-Quellcode:
function TForm2.GetUserFullname(Domain, Username: String): string;
var
  usr: IADsUser;
  s: string;
begin
  result := 'Unknown';
  ADsGetObject('WinNT://' + Domain + '/' + Username, IADsUser, usr);
  assert(usr <> nil);
  s := usr.FullName;
  result := s; // hier ist die Welt noch in Ordnung
end; // -> Exceptions "access violation"
Gruss
MarLe
  Mit Zitat antworten Zitat
Udontknow

Registriert seit: 17. Jun 2002
223 Beiträge
 
#2

Re: ADS - Fullname

  Alt 26. Jan 2007, 09:31
Hallo!

Ist ein wenig ins Blaue hineingeraten, aber sehr wahrscheinlich handelt es sich bei IADSUser um ein Interface. Interfaces werden ja automatisch freigegeben, sobald sie out-of-scope gehen, das heisst, sobald der Compiler in diesem Falle die lokale Variable usr freigeben will, geschieht implizit ein Aufruf der Methode _Release.

Delphi-Quellcode:
ADsGetObject('WinNT://' + Domain + '/' + Username, IADsUser, usr);
try
  assert(usr <> nil);
  s := usr.FullName;
finally
  USR:=NIL; // <- Hier sollte der Fehler direkt auftauchen
end;
Und innerhalb dieser Release-Routine oder im Destruktor des dahinterliegenden Objektes kracht es dann wohl. Vielleicht gibt es eine explizite DeInit-Routine, die unbedingt vor Freigabe des Interfaces aufgerufen werden muss? Schau doch mal ins MSDN, vielleicht hilft dir das weiter.

Cu,
Udontknow
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#3

Re: ADS - Fullname

  Alt 26. Jan 2007, 12:08
Danke für den Tipp.

IADsUser ist ein Interface

Delphi-Quellcode:
// *********************************************************************//
// Interface: IADsUser
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {3E37E320-17E2-11CF-ABC4-02608C9E7553}
// *********************************************************************//
  IADsUser = interface(IADs)
    ['{3E37E320-17E2-11CF-ABC4-02608C9E7553}']
    function Get_FullName: WideString; safecall;
    procedure Set_FullName(const retval: WideString); safecall;
    property FullName: WideString read Get_FullName write Set_FullName;
    ...
Ein usr := nil; hat nix gebracht.

Du hast schon recht wenn ich ein Objekt instantiere (geschieht hier anscheinend über die Hilfsmethode ADsGetObject)
muss ich auch dann den reservierten Speicher wieder freigegeben.
Hab da noch folgendes entdeckt
function FreeADsMem(aPtr: Pointer): BOOL; forward; Diese Funktion wird in dem besagten Downloadbeispiel aber nirgends benutzt?!?
  Mit Zitat antworten Zitat
Udontknow

Registriert seit: 17. Jun 2002
223 Beiträge
 
#4

Re: ADS - Fullname

  Alt 26. Jan 2007, 16:33
Du hast mich ein wenig falsch verstanden. Da es ein Interface ist, musst du normalerweise eben gerade NICHT dafür sorgen, das Objekt eigenhändig freizugeben. Interfaces verfügen über eine Referenz-Zählung, sobald sie feststellen, daß von aussen keine Objekte mehr das Interface "offenhalten", wird automatisch der Destruktor des Objekts, das dieses Interface unterstützt, aufgerufen. Und da vermute ich auch den Fehler. Evtl. benutzt du eine falsche Version der ActiveX-DLL, in der das Objekt implementiert ist? Vielleicht gibt es neue Interfaces, die stattdessen zu nutzen sind, wobei es dann aber eigentlich unsinnig ist, das Objekt weiterhin das Interface unterstützen zu lassen, wenn es dann fehlerhaft arbeitet...

Mit dem Code wollte ich dir lediglich zeigen, daß es daran liegt, daß das Interface freigegeben wird, es sollte keine Lösung sein.
Ein hässlicher und unsauberer Workaround wäre natürlich ein try/except um das NIL-Setzen der Interface-Variable, aber wenn sonst nichts hilft...

Cu,
Udontknow
  Mit Zitat antworten Zitat
Udontknow

Registriert seit: 17. Jun 2002
223 Beiträge
 
#5

Re: ADS - Fullname

  Alt 26. Jan 2007, 17:16
Hallo nochmals,

habe mir mal die Mühe gemacht, dasselbe ohne diese Wrapper-Dateien zu machen. Du musst zuerst aber die TLB-Datei erzeugen:
Menü\Komponente Importieren\Typbibliothek importieren, anschliessend "Active DS Type Library" auswählen. Zweimal weiter klicken und Fertig stellen, anschliessen wird eine Unit mit Namen ActiveDS_TLB angelegt, diese solltest du dann in einem neuen Projekt in die uses-Klausel mitaufnehmen.

Die ADSGetObject-Routine habe ich einfach statisch ins Hauptformular eingebunden:
function ADsGetObject(pwcPathName: PWideChar; const xRIID: TGUID; var pVoid): HResult; stdcall; external 'activeds.dll'; Das ist der Code, den ich für eine Namensauflösung dann einsetze:
Delphi-Quellcode:
var
  usr: IADSUser;
  pc:array[0..255] of WideChar;
  s:String;
begin
  s:='WinNT://'+Edit_Domain.Text+'/'+Edit_Kennung.Text;
  StringToWideChar(S,PC,Length(S)+1);

  ADsGetObject(pc, IADsUser, usr);
  if not Assigned(usr) then
    Edit_Name.Text := 'Unknown'
  else
    Edit_Name.Text := usr.FullName;
end;
Bei mir klappts. Allerdings habe ich ganz schöne Schwierigkeiten, von normalen Strings in PWideChar umzuwandeln...

Cu,
Udontknow
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#6

Re: ADS - Fullname

  Alt 31. Jan 2007, 14:47
Danke für deine Mühe.
Deine Methode funktioniert zwar, allerdings sind in der adshlp.pas noch einige andere Methoden die in dem Beispiel benutzt werden, die müsste ich auch alle umlegen.

Ehrlich gesagt blicke ich da nicht ganz durch warum es in der ursprünglichen Variante am Ende kracht.
Wenn ich die Funktion ohne Rückgabewert deklariere und den Wert innerhalb der Funktion ausgebe z.B. in einem Memo kracht's nicht.
Liegt's vielleicht an der Stringumwandlung ???
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

Re: ADS - Fullname

  Alt 31. Jan 2007, 19:15
Hallo MarLe,

ich möchte es mal so erklären.

IADsUser ist ein Interface, dh. die darüber referenzierten Objekte sind tasächlich schon vorhanden.
In diesem Fall im Active Directory. Über ADsGetObject holst Du dir einen 'Zugriff' auf das Objekt
und möchtest eine bestimmtem Wert zwischenspeichern.
Delphi-Quellcode:
  ADsGetObject('WinNT://' + Domain + '/' + Username, IADsUser, usr);
  assert(usr <> nil);
  s := usr.FullName;
Da Referenzen auf Interface-Objecte nicht frei gegeben werden (müssen/können/dürfen); i.d. Fall dürfen,
da ansonsten das referenzierte Objekt in der ADS freigegeben wird, wird legendlich die Referenz auf
das Objekt gelöscht. Sprich "usr = nil", ohne Dein zutun, da usr nicht mehr benötigt wird.

Da jedoch S := usr.FullName; auch nur eine Referenz ist und damit auch
  Result := S; werden auch diese Referenzen gelöscht, und es kommt zur Zugriffsverletzung.

Ich hoffe es bringt etwas für das Verständnis.

Vielleicht Morgen etwas mehr.

Gruss
  Mit Zitat antworten Zitat
MarLe

Registriert seit: 13. Jan 2005
83 Beiträge
 
Delphi XE2 Professional
 
#8

Re: ADS - Fullname

  Alt 1. Feb 2007, 12:31
Aha, das leuchtet mir ein.
Allerdings hatte ich gedacht dass ich mit der Zuweisung auf eine Variable den Wert bekomme.
Sonst hätte ich ja auch nur
result := usr.FullName; verwenden können.
d.h. jetzt stellt sich die Frage wie ich aus dieser Referenz zu einer normalen Stringvariable komme?
  Mit Zitat antworten Zitat
Udontknow

Registriert seit: 17. Jun 2002
223 Beiträge
 
#9

Re: ADS - Fullname

  Alt 1. Feb 2007, 13:30
Zitat von Alter Mann:


Da jedoch S := usr.FullName; auch nur eine Referenz ist und damit auch
  Result := S; werden auch diese Referenzen gelöscht, und es kommt zur Zugriffsverletzung.
Hallo!

Ich habe immer gedacht, ich verstehe etwas von Interfaces, aber du bringst mich ziemlich in Verwirrung.

S := usr.FullName; ist doch letztendlich nichts anderes als der Aufruf der im Interface deklarierten Methode Get_FullName und eben Zuweisung des Ergebnisses dieser Methode an eine Variable. Was soll an diesem Befehl denn nun eine Referenz sein? Und was soll denn da an Referenzen gelöscht werden?
Solange die Variable USR weder auf NIL gesetzt wird noch "out of scope" geht (also z.B. bei lokalen Variablen beim Verlassen einer Prozedur), wird da keine Referenz freigegeben.

Was genau willst du also eigentlich sagen? Eine Erklärung, wieso es bei meiner Variante klappt, und bei der ursprünglichen nicht, sehe ich hier nicht...

Cu,
Udontknow
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#10

Re: ADS - Fullname

  Alt 1. Feb 2007, 13:31
Hallo,

ihr bringt mich alle ziemlich in Verwirrung. Ich würde es mal so versuchen:

Delphi-Quellcode:
function GetUserFullname(Domain, Username: string): string;
var
  usr: IADsUser;
  ws: WideString;
begin
  ws := 'WinNT://' + Domain + '/' + Username;
  if ADsGetObject(PWideChar(ws), IID_IADsUser, usr) = S_OK
    then Result := usr.FullName
    else Result := 'Unknown';
end;
Getippt und nicht getestet.

Grüße vom marabu
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz