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:
Ach ja, wenn die Exe nicht in der Entwicklungsumgebung gestartet wird, erscheint nicht mal eine Fehlermeldung, das Programm beentet einfach automatisch!// 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; Ihr könnt euch das Beispielprogramm gerne mal anschauen. Ich versteh die Welt nicht mehr :stupid: |
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 |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Sowas passiert auch gerne, wenn man über die Länge einens Speicherbereichs hinausschreibt.
|
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:
Bin mir aber absolut nicht sicher, ob ich hier jetzt eventuell doch irgendwas durcheinander werfe. Aber einen Versuch ist es ja vielleicht doch wert ;-)
// 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; Der Fehler ist jedenfalls in den Innereien dieses Befehls zu suchen:
Delphi-Quellcode:
Wo ist CBF definiert, eventuell hilft hier eine Veränderung von global nach lokal oder rein in die Klasse oder raus aus der Klasse.
ADsMgr.ADSGroups.EnumAllGroups(CBF);
|
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:
Das läßt sich besser Debuggen.
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; Ev. hilft auch ein SetLength (auf txt und txt1). Intern (TEADSObject.DirectorySearch) wird ja auch mit SetLength gearbeitet. Heiko |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
Zitat:
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:
Zitat:
Zitat:
Kennt jemand die Units: ADsTLB, adshlp, AdsErr ich find keine neueren Versionen. Zitat:
|
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
Zitat:
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. |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
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:
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.
procedure TForm1.Button1Click(Sender: TObject);
begin try ADsMgr.ADSGroups.EnumAllGroups(CBF); finally Caption := 'Zugriffsverletzung'; end; end; |
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:
auf:
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;
Delphi-Quellcode:
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,
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; 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; |
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. |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
hänge mal das Projekt wieder komplett an, wie im 1. Posting. Heiko |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Liste der Anhänge anzeigen (Anzahl: 1)
gesagt getan. :stupid:
|
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 |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
Zitat:
|
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
@hoika, konntest du evt. schon etwas testen?
|
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?
|
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:
Dann funktioniert auch die Suche (wieder).
// *********************************************************************//
// 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; Viele Grüße |
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:
So wird die Funktion aufgerufen:
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;
Delphi-Quellcode:
Ich geh schon fast wieder die Wände hoch... das Problem besteht schon seit Wochen und ich kriegs einfach nicht raus... !!!
...
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; ... 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:
Sowas gibts doch gar nicht?!
function TFrameUsers.ChangeAccountName: Boolean;
begin result := AdsMgr.ADSUsers.ChangeAccountName(ADSPATH_OF_CURRENT_USER, EdSAMAccountName.Text); end; 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...?? |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
Zitat:
Was passiert denn bei der folgenden Änderung?
Delphi-Quellcode:
und was passiert hier?
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; ...
Delphi-Quellcode:
und einen hab' ich noch:
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; ...
Delphi-Quellcode:
und noch einen:
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?
Delphi-Quellcode:
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.
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? Da war mal in irgendeinem meiner Programme mal was, aber da komme ich nicht mehr an die Sourcen :-( |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
ShowMessage(EdContainerPath.Text); // <--- ZUGRIFFSVERLETZUNG jetzt hier?
Zitat:
Delphi-Quellcode:
"txt := '- Benutzer wurde erfolgreich nach "'+EdContainerPath.Text+'" verschoben.' + #13 // <--- ZUGRIFFSVERLETZUNG jetzt weg?
Zitat:
|
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. |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Moin, Moin
warum passiert es hier? Zitat:
mehr gebraucht werden(aus Sicht des Interface). Beispiel:
Delphi-Quellcode:
Egal ob der Aufruf erfolgreich war oder nicht, sContainerPath wird aus Sicht des Interfaces nicht mehr
...
sContainerPath := EdContainerPath.Text; if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then txt := '- Benutzer wurde erfolgreich nach "'+sContainerPath+'" verschoben.' // <--- ZUGRIFFSVERLETZUNG !!! ... benötigt, deshalb die Zugriffsverletzung. Ein:
Delphi-Quellcode:
wird jedoch funktionieren, da ja mit EdContainerPath.Text weiter gearbeitet wird.
...
sContainerPath := EdContainerPath.Text; if AdsMgr.ADSObject.MoveTo(ADSPATH_OF_CURRENT_USER, sContainerPath) then txt := '- Benutzer wurde erfolgreich nach "'+ EdContainerPath.Text +'" verschoben.' ... 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 |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
Zitat:
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. |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
Delphi-Quellcode:
txt := '- Benutzer wurde erfolgreich nach "'+ EdContainerPath.Text +'" verschoben.'
Zitat:
|
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
wie wäre es mit
Delphi-Quellcode:
und
function TFrameUsers.ChangeAccountName(const sAccountName : String): Boolean;
begin result := AdsMgr.ADSUsers.ChangeAccountName(ADSPATH_OF_CURRENT_USER, sAccountName); end;
Delphi-Quellcode:
Wenn das auch nicht geht, dann ziehe ich mich aus dem Thema zurück und will nie mehr was mit ADS zu tuen haben ;-)
...
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; ... |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
|
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 :-( |
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? |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
Zitat:
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 ;-) |
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:
Diese nicht!!!!!!!!!!!!!
{******************************************************************************}
// 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;
Delphi-Quellcode:
)=+"?ç(+&"ç+"()*(+"(*ç/ 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.
{******************************************************************************}
// 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; 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; |
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 |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
weder
Delphi-Quellcode:
noch
if not Assigned(sEditedFields) then
ShowMessage('asdf');
Delphi-Quellcode:
Zeigen die Message an! > Ich kanns mir nicht erklären. Wahrscheinlich wird meine StringList durch die Kuriositäten von ADSI zerstört?!
if sEditedFields = nil then
ShowMessage('asdf'); 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! |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
Wie kannst du dir das erklären Alter Mann? |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Habe nochmals intensiv an deiner Aussage hier:
Zitat:
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 ? ;-) |
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 |
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 ;-) |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Sag mal, ist diese Unit mit TADSManager von dir?
|
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
|
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. |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
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:
Es funktioniert wenn ich anschliessend nicht auf die Parameter sOldObjectPath und EdContainerPath.Text zugreiffe, wenn ich das tue gibts die alt Bekannt Zugriffsverletzung...// 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; 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. |
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