Entwickler-Ecke

Sonstiges (Delphi) - Wie geht FOR EACH OBJECT in APPLICATION.TEST


Shadow110 - Mo 26.04.04 22:42
Titel: Wie geht FOR EACH OBJECT in APPLICATION.TEST
Hallo.

Ich habe folgendes.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);
var
theserver:OLEVariant;
begin
try

  theserver :=createoleobject('MetaFrameCOM.MetaFrameServer');
  theserver.initialize(MetaFrameWinSrvObject, 'W2KSV1');

//!!!!! Hier bräuchte ich sowas.. For each anApp in theserver.application do....  

except
  showmessage('Befehl konnte nicht ausgeführt werden!');
end;
end;

Danke euch schon mal

Grüße
Alex


Stauch - Di 27.04.04 09:48

Zitat aus der Delphi-Hilfe
Zitat:
Die Eigenschaft Components ermöglicht über einen Index den Zugriff auf alle Komponenten, die der Komponente untergeordnet sind.


Ich denke, das funktioniert als for-each - Äquivalent ganz gut

C.


Delete - Di 27.04.04 10:33

Wird in dem Fall wohl nicht gehen, weil du den Kommentar übersehen oder falsch verstanden hast
Shadow110 hat folgendes geschrieben:

Delphi-Quelltext
1:
//!!!!! Hier bräuchte ich sowas.. For each anApp in theserver.application do....                    

Weil die OleVariant-Variable "theserver" kein Form-Objekt ist und daher auch keine Komponenten (im Sinne der VCL) enthält, kann man sie auch mit "Components" nicht ansteuern.

@Shadow110: Wenn "theserver.application" ein normales Array ist, dann kannst du IMHO auch mit einer gewöhnlichen for-Schleife auf die einzelnen Elemente zugreifen. Mal so (ohne Gewähr, weil ich das Objekt "MetaFrameCOM.MetaFrameServer" nicht kenne):

Delphi-Quelltext
1:
2:
3:
4:
for i := 0 to theserver.application - 1 do
begin
  { ... }
end;

Wie gesagt: nur auf gut Glück. Wenn du mir erzählst, was der Code machen soll und wo man was dazu nachlesen kann, dann könnte man dir vielleicht noch besser helfen.


Stauch - Di 27.04.04 11:00


Quelltext
1:
Weil die OleVariant-Variable "theserver" ... keine Komponenten (im Sinne der VCL) enthält, kann man sie auch mit "Components" nicht ansteuern.                    


OK, das habe ich übersehen.
@shadow110: Sorry

C.


Shadow110 - Di 27.04.04 13:04

Hallo.

Vielen Dank schon mal für eure Hilfe!

Es handelt sich dabei um ein MFCOM Object. Das ist die COM Schnittstelle von Citrix Metaframe.
Ein Addon für die Terminalserver Funktion von Microsoft.

Die Doku dazu hat so ca 920 seiten.. das will ich jetzt niemandem antun.. Aber hier mal die relevanten Auszüge daraus...

Ein Beispiel in VB:



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
<package>

    <job id="AddAdmins">


        <reference object="MetaFrameCOM.MetaFrameFarm"/>

        <script language="VBScript">
        
            Dim NewAdmin, theFarm, theServer

            '
            ' Create the farm object.
            '
            Set theFarm = CreateObject("MetaFrameCOM.MetaFrameFarm")
                       '
            ' Initialize the farm object.
           
            theFarm.Initialize MetaFrameWinFarmObject

            ' Add the new admins for each server in the farm.


Quelltext
1:
2:
              // Das hier ist die Stelle, die ich in Delphi irgendwie nicht hinbekomme.
               For each theServer in theFarm.Servers



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
      Set NewAdmin = theFarm.AddAdmin
        
                NewAdmin.AdminType = MFAdminPermissionFullAccess
                NewAdmin.Enable = 1
                NewAdmin.AAType = MFAccountAuthorityNTDomain
                NewAdmin.AAName = theServer.ServerName
                NewAdmin.AccountType = MFAccountLocalGroup
                NewAdmin.AccountName = "Administrators"
                NewAdmin.SaveData

                if Err.Number <> 0 Then
                    WScript.Echo "Can't save Admin object"
                    WScript.Echo "(" & Err.Number & ") " & Err.Description
                    WScript.Echo ""
                    WScript.Quit Err.Number
                End if           
            Next
            

        </script>

    </job>

</package>




Set theFarm = CreateObject("MetaFrameCOM.MetaFrameFarm")
theFarm.Initialize MetaFrameWinFarmObject
// Nach dem Einbinden der entsprechenden TypBibliothek in Delphi kann man das entsprechend nachbauen

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure test;
var
thfarm:OLEVariant;
begin
try
  thefarm := createoleobject('MetaframeCOM.MetaframeFarm');
  thefarm.initialize(MetaframeWinFarmObject);
//Jetzt zum Beispiel
showmessage(thefarm.farmname);


So, es gibt jetzt: theFarm.servers (wie im VB Beispiel oben) Was ein "Enumerator object auf Metaframeservers darstellt. Das könnte man auch direkt verwenden:

Delphi-Quelltext
1:
2:
theserver:= createoleobject('MetaframeCOM.MetaframeServer');
theserver.initialize(MetaframeWinFarmObject,'Testserver');


Aber ich muss es über das Farm Object ansprechen, da ich mit allen Servern (die Anzahl und Namen weis ich vorher nicht) etwas machen möchte.

Die Beschreibung zu den Objekten hierzu:




Wäre super, wenn ihr mir da helfen könntet.

Falls es sich jemand antuen möchte, hier der Link zu der MFCOM Referenz:
http://support.citrix.com/servlet/KbServlet/download/2603-102-8989/CitrixServer_SDK_MFCOM_2_3.pdf

Viele Grüße
Alex


Delete - Di 27.04.04 13:40

Also, wenn mich nicht alles täuscht (ich schieb meine Unkenntnis einfach mal auf mein mangelndes VBS-Wissen), dann ist die "For Each"-Schleife in diesem Beispiel

Quelltext
1:
2:
3:
4:
5:
6:
Dim strTypes
strTypes = Array("Erster", "Zweiter", "Dritter", "Vierter")

For Each strFileExt in strTypes
  WScript.Echo strFileExt
Next

das gleiche wie die "For"-Schleife in diesem

Quelltext
1:
2:
3:
For I = 0 To 3
  WScript.Echo strTypes(I)
Next

Der Unterschied ist lediglich, dass bei "For Each" das jeweilige Array-Element gleich der Variablen "strFileExt" zugewiesen wird, während ich bei "For" auf das Array zugreifen und den Schleifenwert als Index übergeben muss.

Ausgehend davon behaupte ich jetzt einfach mal, dass du das gleiche auch mit deinem Beispiel machen kannst. Das größte Problem wird wohl der Bereich des Arrays sein, der bei "For Each" keine Rolle spielt (weil er automatisch richtig benutzt wird). Bei "For" musst du wissen, was der kleinste und was der größte Wert ist. Aber da in solchen Fällen fast immer bei Null begonnen wird, dürfte es wohl so aussehen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
For I = 0 To theFarm.Servers.Count - 1
  ' usw.

  NewAdmin.AAName = theFarm.Servers(I).ServerName

  ' usw.
Next

Das würde ich, an deiner Stelle, jetzt einfach mal mit einer Kopie dieser VBS-Datei probieren. Und wenn keine Fehler auftreten, dann kannst du diese Schleife nahezu 1:1 nach Delphi umsetzen. Bis auf den Schleifenwert "I", den du bei Delphi in eckigen Klammern übergeben müsstest.
Falls ".Count" nicht klappt, probier´s notfalls auch mal mit ".Length". Üblich in VBS sollte aber ".Count" sein.

Edit: zweite Schleife gefixt


Shadow110 - Di 27.04.04 15:17

Hi.

Danke für deine Mühe. Aber leider kann man das nicht wie ein Array ansprechen. In VB habe ich das jetzt nicht getestet nur unter Delphi.

Eine .Count gibt es da auch nicht. Oder Lenght. Das kennt er alles nicht.

Das ist irgendwie so ein Enumerator Object.. Man müsste ihm irgendwie sagen.. fang beim ersten an.. und dann nextobject.. oder sowas.. Hmm...

Bin mal gespannt, ob ich da was finde...

Grüße
Alex


Shadow110 - Di 27.04.04 15:23

Hab noch was vergessen...

In VB.Net sieht das so aus:

DIM srv as IMetaFrameServer
for each srv in farm.servers
xyz
next

----------------------

Es fehlt mir in Delphi irgendwie nur das for each....

Es gibt zwar ForEach aber das ist eine Methode von TCustomBucketList.... und hat nicht wirklich was damit zu tun. :D

Grüße
Alex


Shadow110 - Di 27.04.04 22:09

Hab noch was gefunden:

http://www.wehlou.com/Code/d6_items.htm#Foreach


Vielleicht kann sich das mal jemand ansehen. Ich werde das gleich mal testen.

Grüße
Alex


Shadow110 - Mi 28.04.04 02:14

FUNKTIONIERT!!

Die Unit aus dem vorherigen Post eingebunden und dann folgendes:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var
  thefarm,theapp:OLEVariant;
  foreach:IForEach;
begin
try
  thefarm := createoleobject('MetaFrameCOM.MetaFrameFarm');
  thefarm.initialize(MetaFrameWinFarmObject);
  foreach:=makeforeach(thefarm.Applications);

    while foreach.Next(theapp) do begin
  showmessage(theapp.Appname);
  end;

except
  showmessage('Befehl konnte nicht ausgeführt werden!');
end;


Viele Grüße
Alex
(mittlerweile ganz schön müde..)


Delete - Mi 28.04.04 12:23

Herzlichen Glückwunsch. :)
(ist nicht ironisch gemeint)