Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Zugriffsverletzung ADSI, so was komisches hab ich noch nie.. (https://www.delphipraxis.net/146499-zugriffsverletzung-adsi-so-komisches-hab-ich-noch-nie.html)

cherry 21. Jan 2010 06:37


Zugriffsverletzung ADSI, so was komisches hab ich noch nie..
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Leute

Langsam aber sicher verzweifle ich an folgender Problematik:

- Ich arbeite an einem Benutzerfreundlichen AD Programm, Benutzer erstellen, ändern löschen usw.
- Ich verwende folgene Units: ADsTLB, adshlp, AdsErr (Im Download enthalten)

Zum Problem...

Ich arbeite in diesem Zusammenhang an einer Unit, die den Zugriff aufs AD sehr simpel gestalten soll. Nun kommt es sehr oft zu "unerklärlichen" Zugriffsverletzungen.
Schauen wir uns folgendes Beispiel an:

Delphi-Quellcode:

// Endet in Zugriffsverletzung
procedure TForm1.Button1Click(Sender: TObject);
begin
  ADsMgr.ADSGroups.EnumAllGroups(CBF);
  Caption := 'Zugriffsverletzung'; // <-- Zugriffsverletzung immer bei der darauf folgenden Zeile, egal was hier steht.
end;

// Endet NICHT in Zugriffsverletung
procedure TForm1.Button2Click(Sender: TObject);
begin
  DUMMY;
  Caption := 'KEINE Zugriffsverletzung';
end;

// Dummy function ermöglicht das Ausführen der Funktion ohne Zugriffsverletzung
procedure TForm1.DUMMY;
begin
  ADsMgr.ADSGroups.EnumAllGroups(CBF);
end;
Ach ja, wenn die Exe nicht in der Entwicklungsumgebung gestartet wird, erscheint nicht mal eine Fehlermeldung, das Programm beentet einfach automatisch!
Ihr könnt euch das Beispielprogramm gerne mal anschauen. Ich versteh die Welt nicht mehr :stupid:

Bbommel 21. Jan 2010 08:32

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,

ich habe mir das Projekt jetzt noch nicht runtergeladen, sondern glaube einfach mal deiner Fehlerbeschreibung. :) Ähnliche Effekte habe ich auch ein bis zwei Mal im Jahr - normalerweise hat das dann mit der Stelle selbst, an der die AV auftritt, eher wenig zu tun, sondern liegt daran, dass ich mir irgendwie den Speicher zerschossen habe. Beliebte Ursachen dafür sind Zugriffe auf Objekte, die ich schon freigegeben hatte, oder falsche Typecasts, so dass ich auf Eigenschaften eines Objekts zugreifen möchte, die es gar nicht hat.

Dass sich das Programm dann mit und ohne Debugger völlig anders verhalten hat, hatte ich dann auch gerne mal - klar, dann "liegt" ja sicherlich auch so einiges anders im Speicher und dadurch taucht dann die AV nicht auf.

Viel Spaß beim Suchen. :)

Bis denn
Bommel

Sunlight7 21. Jan 2010 08:45

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Sowas passiert auch gerne, wenn man über die Länge einens Speicherbereichs hinausschreibt.

nahpets 21. Jan 2010 08:53

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,

kann mich schwach ein ein ähnliches Problem in diesem Umfeld erinnern. Soweit ich das in Erinnerung behalten habe, ließ sich das Problem "simpel" lösen. Zuweisungen nur an lokale Variabeln machen und diese dann an die globeln Variablen... zuweisen. In Deinem Beispiel könnte dann eventuell unterumständen vielleicht ... folgendes helfen:

Delphi-Quellcode:
// Endet hoffentlich nicht mehr in Zugriffsverletzung
procedure TForm1.Button1Click(Sender: TObject);
Var
          sCaption : String;
begin
  ADsMgr.ADSGroups.EnumAllGroups(CBF);
  sCaption := 'jetzt keine Zugriffsverletzung mehr'
  Caption := sCaption; // <-- Zugriffsverletzung nicht mehr immer bei der darauf folgenden Zeile, egal was hier steht.
end;
Bin mir aber absolut nicht sicher, ob ich hier jetzt eventuell doch irgendwas durcheinander werfe. Aber einen Versuch ist es ja vielleicht doch wert ;-)

Der Fehler ist jedenfalls in den Innereien dieses Befehls zu suchen:
Delphi-Quellcode:
ADsMgr.ADSGroups.EnumAllGroups(CBF);
Wo ist CBF definiert, eventuell hilft hier eine Veränderung von global nach lokal oder rein in die Klasse oder raus aus der Klasse.

hoika 21. Jan 2010 10:05

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,

TStringArray2 -> array of array of String uiui ;)

Hast du deinen CBF-Code mal ausgeklammert ?
er sieht aber eigentlich OK aus.

Könnte es sein, dass man hier WideString / AnsiString nehmen muss
Du hast ja D2009, viell. hatte der Autor eine kleinere Delphi-Version. ?


Das mit dem Abstürzen bekommst du übrigens mit try/except hin.


Delphi-Quellcode:
procedure TForm1.CBF(data: TStringArray2);
var
  X,Y : Integer;
  txt : String;
  txt1 : String;
begin
  for X := Low(data) to High(data) do
  begin
    txt := '';
    for Y := Low(data[X]) to High(data[X]) do
    begin
      txt1:= data[X,Y];
      txt := txt + ' > ' + txt1;
    end;
    ListBox1.Items.Add(txt);
  end;
end;
Das läßt sich besser Debuggen.
Ev. hilft auch ein SetLength (auf txt und txt1).
Intern (TEADSObject.DirectorySearch) wird ja auch mit SetLength gearbeitet.



Heiko

cherry 21. Jan 2010 10:43

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von nahpets
Hallo, In Deinem Beispiel könnte dann eventuell unterumständen vielleicht ... folgendes helfen... ...Aber einen Versuch ist es ja vielleicht doch wert ;-) ...

> Dies wäre ja dann auch keine Lösung sondern nur ein anderes Workaraound als ich "vorgeschlagen" habe. Habs troztdem mal ausprobiert. Klappt nicht, wenn ich es so mache wie du vorgeschlagen hast, passiert die Zugriffsverletzung einfach bei dieser Zeile: " sCaption := 'jetzt keine Zugriffsverletzung mehr' "

Zitat:

Zitat von nahpets
Der Fehler ist jedenfalls in den Innereien dieses Befehls zu suchen:
Delphi-Quellcode:
ADsMgr.ADSGroups.EnumAllGroups(CBF);
Wo ist CBF definiert, eventuell hilft hier eine Veränderung von global nach lokal oder rein in die Klasse oder raus aus der Klasse.

> Ich vermute, dass der Fehler in den verwendeten Übersetzungsunits liegt... in ADsTLB, adshlp oder AdsErr...
Die Procedure ADsMgr.ADSGroups.EnumAllGroups ist bestandteil von meiner, eben angesprochenen, Unit die den Zugriff aufs AD sehr simpel gestalten soll. (Name der Unit EExtemporanousMumblings)
Ich verwende in der ganzen Unit nur eine einzige Globale Variable und das ist die Klasse selbst: ADSManager: TADSManager; damit ich die Unit einfach einbinden und loslegen kann und nicht noch Instanzieren muss!

Zitat:

Zitat von Sunklight7
Sowas passiert auch gerne, wenn man über die Länge einens Speicherbereichs hinausschreibt.

> Dann würde mein Workaround aber nicht funktionieren. An dem liegts aus meiner Sicht wohl kaum.

Zitat:

Zitat von hoika
Hallo,
TStringArray2 -> array of array of String uiui ;)

könnte man das auch anders lösen, ich denke wenn ich sowas als Parameter habe muss ich zwingend einen Typ davon machen?!

Zitat:

Zitat von hoika
Hast du deinen CBF-Code mal ausgeklammert ?

Soeben, ja. Die Zugriffsverletzung bleibt.

Zitat:

Zitat von hoika
Könnte es sein, dass man hier WideString / AnsiString nehmen muss
Du hast ja D2009, viell. hatte der Autor eine kleinere Delphi-Version. ?

Der Autor von was? EExtemporanousMumblings ist von mir. > Die fehler kommen entweder von dort, oder was ich vermute: Sie liegen in einer der Units: ADsTLB, adshlp, AdsErr...
Kennt jemand die Units: ADsTLB, adshlp, AdsErr ich find keine neueren Versionen.

Zitat:

Zitat von hoika
Das mit dem Abstürzen bekommst du übrigens mit try/except hin.

Eben nicht: Das ist ja das verdammt komische!!!! Wenn ich ein try except mache, schliesst das Programm einfach ohne meldung!!!!

nahpets 21. Jan 2010 11:19

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,
Zitat:

Zitat von cherry
Der Autor von was? EExtemporanousMumblings ist von mir. > Die fehler kommen entweder von dort, oder was ich vermute: Sie liegen in einer der Units: ADsTLB, adshlp, AdsErr...
Kennt jemand die Units: ADsTLB, adshlp, AdsErr ich find keine neueren Versionen.

Zitat:

Zitat von hoika
Das mit dem Abstürzen bekommst du übrigens mit try/except hin.

Eben nicht: Das ist ja das verdammt komische!!!! Wenn ich ein try except mache, schliesst das Programm einfach ohne meldung!!!!

Den zuletzt genannten Effekt hatte ich auch, eigene Fehlerbehandlung zwecklos, Deine Fehlerortvermutung stimmt mit meinen Erfahrungen überein. Leider komme ich nicht mehr an den alten Quelltext, alter Arbeitgeber, alte Arbeit. Andernfalls könnte ich nachschauen, wie ich seinerzeit (per Workaround) um das Problem herumgekommen bin.

Hast Du sCaption mal als globale Variabel deklariert? Kann mich leider nicht mehr erinnern, was ich seinerzeit wo und wie deklariert hatte, es war aber ziemlich abstruse und ein uneleganter Workaround.

Bbommel 21. Jan 2010 12:50

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von cherry
Ich vermute, dass der Fehler in den verwendeten Übersetzungsunits liegt... in ADsTLB, adshlp oder AdsErr...

Zumindest die ADsTLB könntest du ja selber mal neu machen. Das ist ja nur ein Wrapper für die Datei activeds.tlb aus dem Windows-Systemverzeichnis. Vielleicht würde es ja helfen, diese Bibliothek mal unter D2009 selbst neu zu importieren. Evtl. läuft dann ja alles besser oder du stößt in den Units adshlp und adserr, die ja letztlich auch nur ADsTLB zu verwenden scheinen, eher auf den Kern des Problems.

Ich habe mal versucht, das Problem hier nachzuvollziehen, bin allerdings nicht in einer AD-Umgebung, insofern macht das Programm bei mir auch nur eingeschränkt Sinn. Es meldet aber immerhin, dass es kein ActiveDirectory finden konnte (das fängst du übrigens nicht ab, wodurch dann nachher eine OleException geworfen wird, weil du immer davon ausgehst, dass etwas gefunden wurde) und dann ist alles gut. Ich habe das OnClick-Event mal zu
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  try
     ADsMgr.ADSGroups.EnumAllGroups(CBF);
  finally
     Caption := 'Zugriffsverletzung';
  end;
end;
umgebaut. Eine AV gibt es bei mir nicht mehr. Das nur noch mal als bestätigender Hinweis, dass das Problem wahrscheinlich in den genutzten Units liegt.

cherry 21. Jan 2010 14:23

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Huuuuch... Ich glaub ich hab da eine Spur. Die ADsTLB wurde im Jahre 2007 generiert. Könnte es wohl daran liegen?
Ich hab sie mal neu wrappen lassen...

Nun habe ich aber bei meiner "DirectorySearch" Funktion probleme, ich krieg sie nicht mehr zum laufen:

Folgende deklarationen haben geändert:
von:
Delphi-Quellcode:
function GetNextRow(hSearchResult: THandle): HResult; stdcall;
function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar;
                           dwNumberAttributes: LongWord; out phSearchResult: THandle): HResult; stdcall;
function GetColumn(hSearchResult: THandle; szColumnName: PWideChar;
                       out pSearchColumn: ads_search_column): HResult; stdcall;
function CloseSearchHandle(var hSearchResult: THandle): HResult; stdcall;
auf:
Delphi-Quellcode:
function GetNextRow(var hSearchResult: Pointer): HResult; stdcall;
function ExecuteSearch(pszSearchFilter: PWideChar; var pAttributeNames: PWideChar;
                           dwNumberAttributes: LongWord; out phSearchResult: Pointer): HResult; stdcall;
function GetColumn(var hSearchResult: Pointer; szColumnName: PWideChar;
                       out pSearchColumn: ads_search_column): HResult; stdcall;
function CloseSearchHandle(var hSearchResult: Pointer): HResult; stdcall;
Es reicht aber dann nicht ptrResult auf Pointer zu ändern. Es gibt wieder eine Zugriffsverletzung (Stelle ist markiert). Jedoch stürzt das Programm danach nicht ab,
ist immerhin schon etwas. Kann mir jemand helfen?

Delphi-Quellcode:
procedure TEADSObject.DirectorySearch(searchfilter: string; CallBackFunction: TCallBackResultArray; Attributes: string = 'Name;AdsPath;'; LDAPBeginingPath: string = 'ROOTDSE');
var
  search: IDirectorySearch;
  ptrResult: POINTER;
  opt: ads_searchpref_info;
  dwCount: DWORD;
  hr: HResult;
  col: ads_search_column;

  dwErr: DWord;
  szErr    : array[0..255] of Char;
  szName   : array[0..255] of Char;
  I: Integer;

  ArrResult: TStringArray2;
  ArrResCnt: Integer;
  AttrArray: array of PWideChar;
  Attribute: String;
  empty: Boolean;
begin

  // create an attributes array from the attributes passed by a delimitted string
  for I := 1 to Length(Attributes) do
  begin
    if Attributes[I] = ';' then
    begin
      SetLength(AttrArray, Length(AttrArray)+1);
      getmem(AttrArray[Length(AttrArray)-1], 256);
      StringToWideChar(Attribute, AttrArray[Length(AttrArray)-1], 256);
      Attribute := '';
    end
    else
      Attribute := Attribute + Attributes[I]
  end;

  // for faster search set a LDAPBeginingPath to execute the search within this container
  if LDAPBeginingPath = 'ROOTDSE' then
    LDAPBeginingPath := AdsMgr.ADSController.LDAPPATH;

  // get the search object
  if SUCCEEDED(AdsGetObject(LDAPBeginingPath, IDirectorySearch, search)) then
  begin
    try
      // set parameters
      opt.dwSearchPref := ADS_SEARCHPREF_SEARCH_SCOPE OR ADS_SEARCHPREF_SORT_ON;
      opt.vValue.dwType := ADSTYPE_INTEGER;
      opt.vValue.__MIDL_0010.Integer := ADS_SCOPE_SUBTREE;
      // setting search preferences
      if not SUCCEEDED(search.SetSearchPreference(opt, 1)) then
      begin
        ADsGetLastError(dwErr, @szErr[0], 254, @szName[0], 254);
        ShowMessage(WideCharToString(szErr));
        Exit;
      end;
      // prepare
      dwCount := Length(AttrArray);
      ArrResCnt := 1;
      // execute the search
      hr := search.ExecuteSearch(StringToOleStr(searchfilter), AttrArray[0], dwCount, ptrResult);
      // handle the result if hr is S_OK
      if SUCCEEDED(hr) then
      begin
        // get first row
        hr := search.GetNextRow(ptrResult); // <------------ Dies löst den Fehler aus !!!!
        // repeat until no more rows
        while (hr <> S_ADS_NOMORE_ROWS) do
        begin

          // redim result array
          SetLength(ArrResult, ArrResCnt);
          empty := true;

          // for each attribute you want to get (defined in AttrArray)
          for I := 0 to dwCount -1 do
          begin
            // get column
            if Succeeded(search.GetColumn(ptrResult, AttrArray[I], col)) then
            begin
              if col.pADsValues <> nil then
              begin
                // redim result array (2 dimensional string array)
                SetLength(ArrResult[ArrResCnt-1], I+1);
                // fill values into the result array
                ArrResult[ArrResCnt-1,I] := col.pADsValues^.__MIDL_0010.BackLink.ObjectName;
                empty := false;
              end;
              search.FreeColumn(col);
            end;
          end;
          hr := search.GetNextRow(ptrResult);

          // only redim the result array next time, if there was a value found
          // we dont want empty fields in the result array.
          if not empty then
            Inc(ArrResCnt);

        end;
      end;
      search.CloseSearchHandle(ptrResult);
    finally
      search._Release;
    end;
  end;
  if Length(ArrResult) > 0 then
    CallBackFunction(ArrResult);
end;

cherry 21. Jan 2010 15:21

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Das deklarationsproblem hatten wir schon mal hier

Habe nun die Pointer in THandles geändert, kompilieren geht, nur der Fehler tritt am selben Ort auf.

hoika 21. Jan 2010 15:58

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,

hänge mal das Projekt wieder komplett an,

wie im 1. Posting.


Heiko

cherry 21. Jan 2010 16:53

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Liste der Anhänge anzeigen (Anzahl: 1)
gesagt getan. :stupid:

hoika 22. Jan 2010 05:30

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,

eine Warnung

EExtemporaneousMumblings
Zeile 668 (CallBackFunction)
Variable SD möglicherweise nicht initialisiert

Habe hier kein AD, kann es also nicht testen.

Aber was soll dieses ganze RefCount Zeug ?
Bei jedem Zugriff auf ADsMgr wird der Zähler hochgezählt ?
(Hat aber nichts mit dem Problem zu tun)


Heiko

cherry 22. Jan 2010 08:46

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von hoika
EExtemporaneousMumblings
Zeile 668 (CallBackFunction)
Variable SD möglicherweise nicht initialisiert

danke. Aber das hat ja dann wohl auch nichts mit dem Problem zu tun.

Zitat:

Zitat von hoika
Aber was soll dieses ganze RefCount Zeug ?
Bei jedem Zugriff auf ADsMgr wird der Zähler hochgezählt ?

Hmm... muss ich nochmals überdenken, ich hab da einfach mal was versucht glaube ich. Es ging darum, dass mann das Objekt nicht freigeben kann solange es noch verwendet wird. Aber so funktioniert das sowieso nicht... ist also Schwachsinnig. Aber wie du schon gesagt hast, hat auch das nichts mit dem eigentlichen Problem zu tun. 8-)

cherry 25. Jan 2010 16:20

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
@hoika, konntest du evt. schon etwas testen?

cherry 27. Jan 2010 16:13

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Ich hatte da noch die Vermutung, dass es mit der activeds.dll / .tlb version was zu tun haben könnte?! habe mal alle Windows Updates gemacht, die Datei wurde jedoch nicht aktualisiert. Meine Version: "5.1.2600.5512 (xpsp.080413-2113)"... naja, wieder mal auf dem Holzweg... konnte noch jemand mein Beispiel Testen?

Alter Mann 27. Jan 2010 19:21

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,

noch einer, der in TypLib-Falle tapst :wink:

Es ist mir schon im April 2009 aufgefallen das einige deklarationen/definitionen nicht MSDN-Komform sind.
Du wirs also nicht umhin kommen es per Hand zu überprüfen.

Für IDirectorySearch sei die die Arbeit abgenommen:
Delphi-Quellcode:
// *********************************************************************//
// Schnittstelle: IDirectorySearch
// Flags:    (0)
// GUID:     {109BA8EC-92F0-11D0-A790-00C04FD8D5A8}
// *********************************************************************//
  IDirectorySearch = interface(IUnknown)
    ['{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}']
    function SetSearchPreference(var pSearchPrefs: ads_searchpref_info; dwNumPrefs: LongWord): HResult; stdcall;
    function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar;
                           dwNumberAttributes: LongWord; out phSearchResult: THandle): HResult; stdcall;
    function AbandonSearch(var phSearchResult: THandle): HResult; stdcall;
    function GetFirstRow(var hSearchResult: THandle): HResult; stdcall;
    function GetNextRow(hSearchResult: THandle): HResult; stdcall;
    function GetPreviousRow(var hSearchResult: THandle): HResult; stdcall;
    function GetNextColumnName(var hSearchHandle: THandle; out ppszColumnName: PWideChar): HResult; stdcall;
    function GetColumn(hSearchResult: THandle; szColumnName: PWideChar;
                       out pSearchColumn: ads_search_column): HResult; stdcall;
    function FreeColumn(var pSearchColumn: ads_search_column): HResult; stdcall;
    function CloseSearchHandle(var hSearchResult: THandle): HResult; stdcall;
  end;
Dann funktioniert auch die Suche (wieder).

Viele Grüße

cherry 28. Jan 2010 07:19

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo alter Mann... Erstmal Danke das du dich auch dem Problem angenommen hast...
nur leider ist das nicht mein eigentliches Problem. Ursprünglich ist mein Problem: Unerklärbare Zugriffsverletzungen...

Zum Beispiel endet mein Programm auch nach dieser Methode in einer unerklärbaren Zugriffsverletzung...

Delphi-Quellcode:
function TEADSObject.MoveTo(AdsPathObject, AdsPathNewContainer: string): Boolean;
var
  container: IADsContainer;
  obj: IADs;
  hr: Integer;
  r: Boolean;
begin
  result := true;
  try
    if SUCCEEDED(ADSGetObject(AdsPathObject, IID_IADs, obj)) then
    begin
      if SUCCEEDED(ADSGetObject(AdsPathNewContainer, IID_IADsContainer, container)) then
        container.MoveHere(obj.ADsPath, 'cn='+ExtractValue(obj.ADsPath))
      else
        result := false;
    end
    else
      result := false;
  except
    result := false;
  end;
end;
So wird die Funktion aufgerufen:

Delphi-Quellcode:
...
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, EdContainerPath.Text) then
      txt := '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
...
Ich geh schon fast wieder die Wände hoch... das Problem besteht schon seit Wochen und ich kriegs einfach nicht raus... !!!
Es scheint, als ob die Function "MoveTo" etwas nicht richtig frei gibt oder so.... ich schnalls nicht... Wo kann das her kommen???

Und gerade Witzig daran ist, der Benutzer wird tatsächlich korrekt verschoben...

Wenn ich die Funktion in einer DUMMY-Funktion aufrufe erhalte ich auch KEINE Zugriffsverletzung...

Delphi-Quellcode:
function TFrameUsers.ChangeAccountName: Boolean;
begin
  result := AdsMgr.ADSUsers.ChangeAccountName(ADSPATH_OF_CURRENT_USER, EdSAMAccountName.Text);
end;
Sowas gibts doch gar nicht?!

Hmmm.....

Hab grad nochmal was rausgekriegt:
Wenn in der Zeile wo die Zugriffsverletzung auftritt nur Text steht, also ohne EdContainerPath.Text... dann gibts dort keine Zugriffsverletzung...
Also scheints fast so, dass die Funktion auf dem Parameter sitzt...

Was muss ich bloss ändern...??

nahpets 28. Jan 2010 07:43

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,
Zitat:

Zitat von cherry
So wird die Funktion aufgerufen:

Delphi-Quellcode:
...
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, EdContainerPath.Text) then
      txt := '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
...
Ich geh schon fast wieder die Wände hoch... das Problem besteht schon seit Wochen und ich kriegs einfach nicht raus... !!!
Es scheint, als ob die Function "MoveTo" etwas nicht richtig frei gibt oder so.... ich schnalls nicht... Wo kann das her kommen???

Und gerade Witzig daran ist, der Benutzer wird tatsächlich korrekt verschoben...

Wenn ich die Funktion in einer DUMMY-Funktion aufrufe erhalte ich auch KEINE Zugriffsverletzung...

Delphi-Quellcode:
function TFrameUsers.ChangeAccountName: Boolean;
begin
  result := AdsMgr.ADSUsers.ChangeAccountName(ADSPATH_OF_CURRENT_USER, EdSAMAccountName.Text);
end;
Sowas gibts doch gar nicht?!

Hmmm.....

Hab grad nochmal was rausgekriegt:
Wenn in der Zeile wo die Zugriffsverletzung auftritt nur Text steht, also ohne EdContainerPath.Text... dann gibts dort keine Zugriffsverletzung...
Also scheints fast so, dass die Funktion auf dem Parameter sitzt...

Was muss ich bloss ändern...??

meine Vermutung geht dahin, dass MoveTo Dir (wie auch immer) EdContainerPath.Text zerschießt. Die passt ja auch zu den andernorts schon genannten Vermutungen in Bezug auf den Einsatz von Variabeln.

Was passiert denn bei der folgenden Änderung?
Delphi-Quellcode:
Var
    sContainerPath : String;
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
      txt := '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG jetzt weg?
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
...
und was passiert hier?
Delphi-Quellcode:
Var
    sContainerPath : String;
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
      txt := '- Benutzer wurde erfolgreich nach "'+sContainerPath+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG nicht weg?
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
...
und einen hab' ich noch:
Delphi-Quellcode:
Var
    sContainerPath : String;
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, EdContainerPath.Text) then
      txt := '- Benutzer wurde erfolgreich nach "'+sContainerPath+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG jetzt weg?
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
...
  ShowMessage(EdContainerPath.Text); // <--- ZUGRIFFSVERLETZUNG jetzt hier?
und noch einen:
Delphi-Quellcode:
Var
    sContainerPath : String;
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
      txt := '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG jetzt weg?
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
...
  ShowMessage(sContainerPath); // <--- ZUGRIFFSVERLETZUNG jetzt hier?
Irgendwie meine ich mich daran erinnern zu können, dass auf Variabeln, die im Zusammenhang mit ADSObject benutzt wurden, nachher nicht mehr zugegriffen werden konnten, ohne auf eine Zugriffsverletzung zu stoßen.
Da war mal in irgendeinem meiner Programme mal was, aber da komme ich nicht mehr an die Sourcen :-(

cherry 28. Jan 2010 07:54

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von nahpets
...

Was passiert denn bei der folgenden Änderung?
Delphi-Quellcode:
Var
    sContainerPath : String;
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
      txt := '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG jetzt weg?
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;

Zugriffsverletzung!

Zitat:

Zitat von nahpets
...

und was passiert hier?
Delphi-Quellcode:
Var
    sContainerPath : String;
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
      txt := '- Benutzer wurde erfolgreich nach "'+sContainerPath+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG nicht weg?
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;

KEINE Zugriffsverletung!!!

Zitat:

Zitat von nahpets
...und einen hab' ich noch:
Delphi-Quellcode:
Var
    sContainerPath : String;
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, EdContainerPath.Text) then
      txt := '- Benutzer wurde erfolgreich nach "'+sContainerPath+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG jetzt weg?
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
...
  ShowMessage(EdContainerPath.Text); // <--- ZUGRIFFSVERLETZUNG jetzt hier?

Richtig "geraten" !!! Zugriffsverletung in dieser Zeile:
Delphi-Quellcode:
ShowMessage(EdContainerPath.Text); // <--- ZUGRIFFSVERLETZUNG jetzt hier?
Zitat:

Zitat von nahpets
und noch einen:
Delphi-Quellcode:
Var
    sContainerPath : String;
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
      txt := '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG jetzt weg?
    else
      txt := '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
...
  ShowMessage(sContainerPath); // <--- ZUGRIFFSVERLETZUNG jetzt hier?

Zugriffsverletung in dieser Zeile:
Delphi-Quellcode:
 "txt := '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG jetzt weg?
Zitat:

Zitat von nahpets
Irgendwie meine ich mich daran erinnern zu können, dass auf Variabeln, die im Zusammenhang mit ADSObject benutzt wurden, nachher nicht mehr zugegriffen werden konnten, ohne auf eine Zugriffsverletzung zu stoßen.
Da war mal in irgendeinem meiner Programme mal was, aber da komme ich nicht mehr an die Sourcen :-(

Hmm du scheinst irgendwie recht zu haben... konnstest du damals das Problem lösen?

nahpets 28. Jan 2010 08:39

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,

seinerzeit habe ich den Fehler wegbekommen, aber ich weiß nicht mehr wie. Da ich hier kein ADS habe, kann ich auch nicht ausprobieren, wie das damals wohl war.

Bau Dir für die Zugriffe jeweils Methoden, wie Deinen Dummy, und übergibt den Methoden die Werte als Const-Parameter. Als Rückgabe immer einen Boolean verwenden, mit dem Du den Erfolg abprüfen kannst.

Deine bisherigen Beschreibungen erwecken bei mir den Eindruck, als würde nach dem Zugriff mit ADSObject die im Formular genutzten Komponenten zerschossen. Also diese nicht nutzen, Variabeln "zwischenschalten" und ADS-Zugriffe in eigenen Methoden packen.

Klingt erstmal aufwändig, aber mir fällt da nix besseres ein.

Alter Mann 28. Jan 2010 08:43

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Moin, Moin

warum passiert es hier?
Zitat:

Delphi-Quellcode:
ShowMessage(EdContainerPath.Text); // <--- ZUGRIFFSVERLETZUNG jetzt hier?

Ganz einfach: Es wird mit Interfaces gearbeitet. Das 'schöne' daran das die Variablen freigegeben werden sobald sich nicht
mehr gebraucht werden(aus Sicht des Interface).

Beispiel:
Delphi-Quellcode:
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
txt := '- Benutzer wurde erfolgreich nach "'+sContainerPath+'" verschoben.' // <--- ZUGRIFFSVERLETZUNG !!!
...
Egal ob der Aufruf erfolgreich war oder nicht, sContainerPath wird aus Sicht des Interfaces nicht mehr
benötigt, deshalb die Zugriffsverletzung.

Ein:
Delphi-Quellcode:
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
txt := '- Benutzer wurde erfolgreich nach "'+ EdContainerPath.Text +'" verschoben.'
...
wird jedoch funktionieren, da ja mit EdContainerPath.Text weiter gearbeitet wird.

Es gibt in diesem Zusammenhang noch einige andere Ungereimtheiten, die ich jetzt nicht erklären kann, da ich keine Zugriff
auf meine Dateien/Projekte habe(die liegen zu Hause). Also notfalls noch einmal melden.

Bis Bald

nahpets 28. Jan 2010 08:57

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,
Zitat:

Zitat von Alter Mann
Moin, Moin

warum passiert es hier?
Zitat:

Delphi-Quellcode:
ShowMessage(EdContainerPath.Text); // <--- ZUGRIFFSVERLETZUNG jetzt hier?

Ganz einfach: Es wird mit Interfaces gearbeitet. Das 'schöne' daran das die Variablen freigegeben werden sobald sich nicht
mehr gebraucht werden(aus Sicht des Interface).

Beispiel:
Delphi-Quellcode:
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
txt := '- Benutzer wurde erfolgreich nach "'+sContainerPath+'" verschoben.' // <--- ZUGRIFFSVERLETZUNG !!!
...
Egal ob der Aufruf erfolgreich war oder nicht, sContainerPath wird aus Sicht des Interfaces nicht mehr
benötigt, deshalb die Zugriffsverletzung.

Ein:
Delphi-Quellcode:
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
txt := '- Benutzer wurde erfolgreich nach "'+ EdContainerPath.Text +'" verschoben.'
...
wird jedoch funktionieren, da ja mit EdContainerPath.Text weiter gearbeitet wird.

Es gibt in diesem Zusammenhang noch einige andere Ungereimtheiten, die ich jetzt nicht erklären kann, da ich keine Zugriff
auf meine Dateien/Projekte habe(die liegen zu Hause). Also notfalls noch einmal melden.

Bis Bald

endlich mal 'ne Erklärung die ich verstehe und anhand derer ich das Problem nachvollziehen kann.

Das heißt aber doch, für jeden Zugriff mit ADSObject mache man sich die entsprechende Variabel, weise ihr den entsprechenden Wert zu und greife nachher nie mehr auf diese Variabel zu.
Das passt auch auf die Lösung, an die ich mich zu erinnern glaube.

cherry 28. Jan 2010 09:04

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von Alter Mann
Moin, Moin

Ein:
Delphi-Quellcode:
...
  sContainerPath := EdContainerPath.Text;
if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then
txt := '- Benutzer wurde erfolgreich nach "'+ EdContainerPath.Text +'" verschoben.'
...
wird jedoch funktionieren, da ja mit EdContainerPath.Text weiter gearbeitet wird.

Also irgenwas mach ich noch falsch, denn das klappt bei mir nicht. Ich erhalte immer noch eine Zugriffsverletzung an dieser Stelle:

Delphi-Quellcode:
txt := '- Benutzer wurde erfolgreich nach "'+ EdContainerPath.Text +'" verschoben.'
Zitat:

Zitat von Alter Mann
Es gibt in diesem Zusammenhang noch einige andere Ungereimtheiten, die ich jetzt nicht erklären kann, da ich keine Zugriff
auf meine Dateien/Projekte habe(die liegen zu Hause). Also notfalls noch einmal melden.

Ich wäre dir sehr dankbar wenn du mir diesbezüglich noch mehr informationen geben könntest. Notfalls werde ich dich nochmals dran erinnern... :wink:

nahpets 28. Jan 2010 09:40

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,
wie wäre es mit
Delphi-Quellcode:
function TFrameUsers.ChangeAccountName(const sAccountName : String): Boolean;
begin
  result := AdsMgr.ADSUsers.ChangeAccountName(ADSPATH_OF_CURRENT_USER, sAccountName);
end;
und
Delphi-Quellcode:
...
  if ChangeAccountName(EdContainerPath.Text) then begin
    txt := '- Benutzer wurde erfolgreich nach "'+ EdContainerPath.Text +'" verschoben.';
  end else begin
    txt := '- Benutzer konnte nicht nach "'+ EdContainerPath.Text +'" verschoben werden.';
  end;
...
Wenn das auch nicht geht, dann ziehe ich mich aus dem Thema zurück und will nie mehr was mit ADS zu tuen haben ;-)

cherry 28. Jan 2010 10:14

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von nahpets
Hallo,
wie wäre es mit
Delphi-Quellcode:
function TFrameUsers.ChangeAccountName(const sAccountName : String): Boolean;
begin
  result := AdsMgr.ADSUsers.ChangeAccountName(ADSPATH_OF_CURRENT_USER, sAccountName);
end;
und
Delphi-Quellcode:
...
  if ChangeAccountName(EdContainerPath.Text) then begin
    txt := '- Benutzer wurde erfolgreich nach "'+ EdContainerPath.Text +'" verschoben.';
  end else begin
    txt := '- Benutzer konnte nicht nach "'+ EdContainerPath.Text +'" verschoben werden.';
  end;
...
Wenn das auch nicht geht, dann ziehe ich mich aus dem Thema zurück und will nie mehr was mit ADS zu tuen haben ;-)

Das dies Funktioniert habe ich schon im ersten Beitrag gepostet, nur ist das doch keine Lösung!!!? Ist doch unsauber und sieht auch sch... aus im Quellcode, ich möchte mich weigern solch Code zu erzeugen... :!: Gibts denn keine andere Lösung... muss das eigentlich so sein, oder ist das ein Bug? Ich gehe mal davon aus das da nur Delphi davon betroffen ist, ich habe sowas nämlich noch nie gehört oder gesehen... :kotz:

nahpets 28. Jan 2010 10:42

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,

Alter Mann schreibt aber oben in diesem Zusammenhang, warum die Krücke gebraucht wird. Wer jetzt letztlich "Schuld" an dem Dilemma ist, keine Ahnung :-(

cherry 28. Jan 2010 10:47

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hi...

1. Dann ist also die Lösung: eine Dummy Funktion zu verwenden?!
2. Und warum funktioniert die Dummy Funktion und das Workaround mit den Variablen klappt nicht?
3. Ist das jetzt nur bei Delphi so, oder hat man das Problem auch mit einer anderen Entwicklungsumgebung/Sprache?

nahpets 28. Jan 2010 11:09

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo,
Zitat:

Zitat von cherry
Hi...

1. Dann ist also die Lösung: eine Dummy Funktion zu verwenden?!
2. Und warum funktioniert die Dummy Funktion und das Workaround mit den Variablen klappt nicht?
3. Ist das jetzt nur bei Delphi so, oder hat man das Problem auch mit einer anderen Entwicklungsumgebung/Sprache?

1. ja
2. Weil (vermutlich) bei der Dummyfunktion nur die in ihr verwendeten Variabeln zerschossen werden, es geht wohl nur innerhalb der Funktion was kaputt und die Aussenwelt bleibt unberührt. Ohne die Dummyfunktion übernimmt wohl quasi die Funktion, in der der Aufruf stattfindet, den "Kaputtgehpart" der Dummyfunktion.
3. Kann ich nichts zu sagen, kenne nur Delphi ;-)

cherry 2. Feb 2010 05:32

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hmm super, da hab ich mich schon halbers mit den "DummyFunktionen" abgefunden, da tritt folgendes Phänomen auf:

Diese Funktion endet stets in einer Zugriffsverletung:

Delphi-Quellcode:
{******************************************************************************}
// UI: SAVE USER INFORMATION AFTER EDITING
{******************************************************************************}
procedure TFrameUsers.BtnSaveClick(Sender: TObject);
var
  txt: String;
begin
  txt := '';
  // CHANGE SAMACCOUNTNAME
  if sEditedFields.IndexOf('EdSAMAccountName') > -1 then
  begin
    if ChangeAccountName then
      txt := '- Kontoname wurde auf "'+EdSAMAccountName.Text+'" geändert.' + #13
    else
      txt := '<!> Kontoname konnte nicht geändert werden <!>' + #13;
  end;
  // CHANGE DESCRIPTION
  if sEditedFields.IndexOf('EdDescription') > -1 then // <<<<<<<<<<<<<<<<<<< ZUGRIFFSVERLETZUNG
  begin
    if ChangeDescription then
      txt := txt + '- Beschreibung wurde erfolgreich geändert.' + #13
    else
      txt := txt + '<!> Beschreibung wurde nicht geändert <!>.' + #13;
  end;
  // CHANGE NAMES
  if (sEditedFields.IndexOf('EdLastName') > -1) or (sEditedFields.IndexOf('EdFirstName') > -1) then
  begin
    if ChangeNames then
    begin
      txt := txt + '- Benutzer heisst jetzt "'+EdLastName.Text+' '+EdFirstName.Text+'"' + #13;
      if ChangeCN then
        txt := txt + ' - CN wurde ebenfalls auf "'+EdLastName.Text+' '+EdFirstName.Text+'" geändert. ' + #13
      else
        txt := txt + ' <!> CN konnte nicht geändert werden <!>' + #13;
    end
    else
      txt := txt + '<!> Benutzername konnte nicht geändert werden <!>' + #13;
  end;
  // MOVE USER
  if sEditedFields.IndexOf('EdContainerPath') > -1 then
  begin
    if MoveUser then
      txt := txt + '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13
    else
      txt := txt + '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
  end;
  // FINALIZE
  if txt = '' then
  begin
    txt := 'Sie haben keine Änderungen vorgenommen.'+#13+'Wenn Sie nichts ändern wollen, klicken Sie auf abbrechen.';
    ShowMessage(txt);
  end
  else
  begin
    ShowMessage(txt);
    FreeAndNil(sEditedFields);
    ShowFrame(mdDontClearFields);
  end;
end;
Diese nicht!!!!!!!!!!!!!

Delphi-Quellcode:
{******************************************************************************}
// UI: SAVE USER INFORMATION AFTER EDITING
{******************************************************************************}
procedure TFrameUsers.BtnSaveClick(Sender: TObject);
var
  txt: String;
  sf: TStringList;
begin
  txt := '';
  sf := sEditedFields;
  // CHANGE SAMACCOUNTNAME
  if sf.IndexOf('EdSAMAccountName') > -1 then
  begin
    if ChangeAccountName then
      txt := '- Kontoname wurde auf "'+EdSAMAccountName.Text+'" geändert.' + #13
    else
      txt := '<!> Kontoname konnte nicht geändert werden <!>' + #13;
  end;
  // CHANGE DESCRIPTION
  if sEditedFields.IndexOf('EdDescription') > -1 then
  begin
    if ChangeDescription then
      txt := txt + '- Beschreibung wurde erfolgreich geändert.' + #13
    else
      txt := txt + '<!> Beschreibung wurde nicht geändert <!>.' + #13;
  end;
  // CHANGE NAMES
  if (sEditedFields.IndexOf('EdLastName') > -1) or (sEditedFields.IndexOf('EdFirstName') > -1) then
  begin
    if ChangeNames then
    begin
      txt := txt + '- Benutzer heisst jetzt "'+EdLastName.Text+' '+EdFirstName.Text+'"' + #13;
      if ChangeCN then
        txt := txt + ' - CN wurde ebenfalls auf "'+EdLastName.Text+' '+EdFirstName.Text+'" geändert. ' + #13
      else
        txt := txt + ' <!> CN konnte nicht geändert werden <!>' + #13;
    end
    else
      txt := txt + '<!> Benutzername konnte nicht geändert werden <!>' + #13;
  end;
  // MOVE USER
  if sEditedFields.IndexOf('EdContainerPath') > -1 then
  begin
    if MoveUser then
      txt := txt + '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13
    else
      txt := txt + '<!> Benutzer konnte nicht verschoben werden <!>' + #13;
  end;
  // FINALIZE
  if txt = '' then
  begin
    txt := 'Sie haben keine Änderungen vorgenommen.'+#13+'Wenn Sie nichts ändern wollen, klicken Sie auf abbrechen.';
    ShowMessage(txt);
  end
  else
  begin
    ShowMessage(txt);
    FreeAndNil(sEditedFields);
    ShowFrame(mdDontClearFields);
  end;
end;
)=+"?ç(+&"ç+"()*(+"(*ç/ Was ist denn jetzt schon wieder?! Wie ihr bemerkt habt, verwende ich nur in der ersten if abfrage mein "kopiertes" Objekt sEditedFields' und das klappt schon.
Wenn ich allerdings wie in der ersten Funktion sEditedFields verwende, gibts ne schreeeecklicke Zugriffsverletzung!

Für den Test änderte ich immer nur den sAMAccountName und die Beschreibung, dann tritt die Zugriffsverletung an der markierten Stelle.

Ich meine: Es scheint irgendwie meine StringList "sEditedFields" zu zerstören, nur wie und warum, die gebe ich ja nirgens an eine Funktion weiter die ADSGetObject oder so aufruft, woher die Zerstörungswut????

Ich glaub ich kündige :cry:

PS: Hier noch die Dummy Functions:

Delphi-Quellcode:
{******************************************************************************}
// MOVE USER [DUMMY FUNCTION]
{******************************************************************************}
function TFrameUsers.MoveUser: Boolean;
begin
  result := AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, EdContainerPath.Text);
end;

{******************************************************************************}
// CHANGE ACCOUNT NAME [DUMMY FUNCTION]
{******************************************************************************}
function TFrameUsers.ChangeAccountName: Boolean;
begin
  result := AdsMgr.ADSUsers.ChangeAccountName(ADSPATH_OF_CURRENT_USER, EdSAMAccountName.Text);
end;

{******************************************************************************}
// CHANGE NAMES [DUMMY FUNCTION]
{******************************************************************************}
function TFrameUsers.ChangeNames;
begin
  result := AdsMgr.ADSUsers.ChangeNames(ADSPATH_OF_CURRENT_USER, EdFirstName.Text, EdLastName.Text);
end;

{******************************************************************************}
// CHANGE USERS CN [DUMMY FUNCTION]
{******************************************************************************}
function TFrameUsers.ChangeCN;
begin
  result := AdsMgr.ADSUsers.ChangeCN(ADSPATH_OF_CURRENT_USER, EdFirstName.Text+' '+EdLastName.Text);
end;

{******************************************************************************}
// CHANGE USERS DESCRIPTION [DUMMY FUNCTION]
{******************************************************************************}
function TFrameUsers.ChangeDescription;
begin
  result := AdsMgr.ADSUsers.ChangeDescription(ADSPATH_OF_CURRENT_USER, EdDescription.Text);
end;

Alter Mann 2. Feb 2010 06:57

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Moin, Moin

wodurch wird die ZV den ausgelöst, ist sEditedFields = nil?

Mal etwas anderes, warum fütterst du nicht ein ADSUser-Objekt und speicherst
alle Änderungen auf einmal?

Gruss

cherry 2. Feb 2010 07:18

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von Alter Mann
Moin, Moin

wodurch wird die ZV den ausgelöst, ist sEditedFields = nil?

Mal etwas anderes, warum fütterst du nicht ein ADSUser-Objekt und speicherst
alle Änderungen auf einmal?

Gruss

Hmmm...

weder

Delphi-Quellcode:
if not Assigned(sEditedFields) then
    ShowMessage('asdf');
noch
Delphi-Quellcode:
if sEditedFields = nil then
    ShowMessage('asdf');
Zeigen die Message an! > Ich kanns mir nicht erklären. Wahrscheinlich wird meine StringList durch die Kuriositäten von ADSI zerstört?!

Dein zweiter Vorschlag ist gut, ich werde das bei Gelegenheit so lösen. Aber ich möchte trotzdem rausfinden was hier das Problem ist! Hast du eine Idee? das gibts doch gar net!

cherry 3. Feb 2010 09:02

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von Alter Mann
Ganz einfach: Es wird mit Interfaces gearbeitet. Das 'schöne' daran das die Variablen freigegeben werden sobald sich nicht
mehr gebraucht werden(aus Sicht des Interface).

Anscheinend verhält sich das Ganze aber noch verrückter als bisher angenommen. Ich meine "sEditedFields" wird gar nie verwendet in einer Funktion die ADSI behandelt, aber es scheint so, als ob es trotzdem was vermurgst. Ich bin überzeugt, das meine aktuelle Zugriffsverletung auch durch ADSI ausgelöst wird.

Wie kannst du dir das erklären Alter Mann?

cherry 4. Feb 2010 05:54

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Habe nochmals intensiv an deiner Aussage hier:

Zitat:

Ganz einfach: Es wird mit Interfaces gearbeitet. Das 'schöne' daran das die Variablen freigegeben werden sobald sich nicht
mehr gebraucht werden(aus Sicht des Interface).
herumstudiert.

Die Lösung in diesem Falle war ja, eine Dummy Funktion aufzurufen, damit nur die Funktionsvariablen verschossen werden. Nun, ich verstehe aber nicht wie das Interface überhaupt was zerstören kann.
Ich übergebe ja nicht meine Variablen als Parameter, sondern nur eine Kopie dessen Werte. Wie zum Teufel soll das Interface mir dann z.B. ein Textfeld zerschiessen?

Und bei meinem etwas später aufgetauchten Problem werde ich noch weniger schlau daraus. Es wird mir eine TStringList zerschossen, die nicht mal in der Dummyfunktion verwendet wird. Woher weiss das Interface überhaubt, dass ein solches Objekt vorhanden ist? -Und noch besser wieso wird es zerschossen?

Ich bin momental echt am zweifeln ob es einen Sinn hat so weiter zu Programmieren?! Anscheinend eignet sich Delphi überhaupt nicht für AD sachen. Oder liegt es am AD ? ;-)

Alter Mann 4. Feb 2010 07:58

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hi,

ich bin auch nicht der Interface-Guru, es ist aber so, dass du die Adresse übergibst an der der Inhalt deiner Variablen steht.
Diese Speicheradresse wird nun von dem Interface-Objekt für die jeweilige Aktion verwenden und anschließend freigegeben.

Der Vorteil, du musst dich nicht darum kümmern.

Die Lösung(?) aus dem Dilemma, keine Referenzen sonder 'echte' Kopien (move(StringList.Strings[I], Str, Length(StringList.Strings[I])).

Ich gebe hier nur meine Erfahrung mit ADSI wieder, bitte nicht als generelle Lösung sehen.

Gruss

cherry 4. Feb 2010 08:10

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Lieber Alter Mann

Ich bin froh, dass du diene Erfahrungen mit mir teilst. Ich hoffe du wirst das auch weiterhin tun. ;-) Denn ich verliere langsam aber sicher meinen Verstand, oder eben dass, was noch davon übrig geblieben ist.

1. Ich dachte wenn man bei einer Prozedur die Parameter per var übergibt ist es so wie du gesagt hast. Bei einer "normalen" übergabe, dachte ich, dass es den Wert kopiert.

2. Was ja komisch ist, ist, dass meine StringList gar nichts mit der ADSI Funktion zu tun hat. Und sie trotzdem verschossen wird. Was soll ich also einen Wert kopieren, ich übergebe ihn ja nirgens.
"(move(StringList.Strings[I], Str, Length(StringList.Strings[I]))" bringt mir ja nichts, die Stringlist verwende ich weder in der Dummy Funktion noch in der eigentlichen. Ich verwende die Liste nur in der Funktion in der die Dummy Funktion verwendet wird. >>> Wieso nur wird die Liste Verschossen, hast du da auch eine plausible Erklärung?

Danke schon mal ;-)

Dezipaitor 4. Feb 2010 11:28

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Sag mal, ist diese Unit mit TADSManager von dir?

cherry 4. Feb 2010 12:25

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Dezipaitor
Sag mal, ist diese Unit mit TADSManager von dir?

Ja isse. Kann mitunter schon auch an der liegen! > Hier noch mal separat im Anhang...

Dezipaitor 4. Feb 2010 12:33

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Also, wenn bei mir soetwas passiert, dann gehe ich meist so vor:

Eliminiere alles Unnötige. D.h. extrahiere die Essenz, also das Wesentliche in ein eigenes Projekt ohne Klasse, ohne tolle Tricks und teste es dort.

Die Referenzzählung kommt mir schon etwas suspekt vor, besonders da ich noch nie soetwas gesehen habe, dass nur mit NewInstance statt Create arbeitet. Insbesodere funktioniert die Referenzzählung eh nicht, da sie nie kleiner wird. Wie denn auch?

Also lass mal die Klassen beiseite und teste das AD Search separat.

cherry 15. Feb 2010 15:33

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Dezipaitor
Also lass mal die Klassen beiseite und teste das AD Search separat.

Ok, nach einer Woche Ferien habe ich das jetzt mal gemacht. Ich habe eine neue Testanwendung erstellt mit den Funktionen die Ich testen will.
Dabei ist nun jeglicher Komfort weg, insbesondere halt auch beim GUI...

Bis jetzt hab ich es so verstanden: ADSGetObject zerschiesst mir die Parameter nachdem ADSGetObject diese nicht mehr benötigt.
Dies kann man umgehen indem man die eigentliche Funktionen in DummyFunktionen ausführt. Dies führt dazu, dass nicht die eigentlichen Parameter, sondern die der Dummyfunktion
zerschossen werden, somit kann ich nach dessen Betätigung immer noch auf meine Objekte zugreiffen.

Dies hat eine ganze Weile funktioniert und ich habe einigermassen verstanden wieso und konnte das auch "elegant" (naja, nicht wirklich) umgehen...

Jetzt aber die Ausnahme:

Delphi-Quellcode:
 
  // Benutzer verschieben
  if sEditedFields.IndexOf('EdContainerPath') > -1 then
  begin
    if DummyMoveUser(sOldObjectPath, EdContainerPath.Text) then
      txt := txt + '> Benutzer erfolgreich verschoben' // KEINE ZUGRIFFSVERLETZUNG
      //txt := txt + '> Benutzer erfolgreich von "'+sOldObjectPath+'" nach "'+EdContainerPath.Text+'" verschoben' // ZUGRIFFSVERLETZUNG
    else
      txt := txt + '(!) Benutzer konnte nicht verschoben werden.';
  end;
Es funktioniert wenn ich anschliessend nicht auf die Parameter sOldObjectPath und EdContainerPath.Text zugreiffe, wenn ich das tue gibts die alt Bekannt Zugriffsverletzung...

Ich bitte also wieder mal mehr um eure Mithilfe, denn ich frag mich langsam was mit mir los ist. Oder ob es an Delphi liegt? ich steck im Sumpf, holt mich hier raus! :-D

Danke schon ma...


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:31 Uhr.
Seite 1 von 3  1 23      

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