AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Datenaustausch (Message o.Ä.) von Terminalserver an Client

Datenaustausch (Message o.Ä.) von Terminalserver an Client

Ein Thema von jensw_2000 · begonnen am 20. Sep 2005 · letzter Beitrag vom 22. Sep 2005
Antwort Antwort
Seite 1 von 2  1 2   
jensw_2000
(Gast)

n/a Beiträge
 
#1

Datenaustausch (Message o.Ä.) von Terminalserver an Client

  Alt 20. Sep 2005, 08:49
Hallo zusammen,

ich habe ein kleines CTI Programm geschrieben, das ich jetzt etwas erweitern muss.

Im Prinzip liest das Programm derzeit bein Drücken eines Hotkeys den selektierten Text aus der aktiven Anwendung aus, prüft ob darin eine sinnvolle Telefonnummer steht und wählt diese über TAPI.

Alles schön und gut, aber ein Kunde möchte das Tool jetzt auch mit einer Terminalserver-Applikation verwenden.

Wenn die Terminalserver-App aktiv ist und ich den Hotkey drücke, dann wird dieser nicht an mein lokales System gesendet sondern an den Terminalserver.

Nun frage ich mich ob es möglich ist, ein kleines "Helper-Programm" auf dem Terminalserver laufen zu lassen, das beim Drücken des Hotkeys (in der Terminalsitzung) eine Message o.Ä. an die CTI-Applikation dem Client-PC sendet, damit diese dann die Rufnummer über die TAPI Schnittstelle des Clients wählt ...

Ich habe absolut keine Idee wie man das sinnvoll lösen könnte.

Notfalls mache ich das über eine TCP-Message die das Helper-Programm auf dem Terminaserver an den Client-PC sendet. Wirklich gut gefällt mir die Idee jedoch nicht, weil der administrative Aufwand extrem hoch ist (Port-Forwarding auf jedem Client-Router konfigurieren, Firewalls konfigurieren ...) und weil durch den zusätzlich geöffneten Port auch noch die Sicherheit leidet.


Wie kann man das Problem professionell lösen ?
Ich bin für jeden Hinweis dankbar.


Schöne Grüße,
Jens

  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#2

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 20. Sep 2005, 09:25
Läßt sich das in deinem Fall vielleicht mit Virtual Channels erleichtern?

Guck dir mal die WTSVirtualChannel*-Funktionen an - z.B MSDN-Library durchsuchenWTSVirtualChannelWrite
  Mit Zitat antworten Zitat
Benutzerbild von MarcoWarm
MarcoWarm

Registriert seit: 10. Sep 2003
Ort: Großhennersdorf
532 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 20. Sep 2005, 09:32
der offizielle Weg sind die VirtualChannels. Darüber wird auch das SharedClipboard des Terminalservers realisiert.

1. der einfache, jedoch unelegante Weg ist, die Zwischenablage zu verwenden. Ok da ist dein Vorschlag mit dem extra TCP-Server doch besser.

2. ich sag mal wie es bei uns läuft. Wir haben auf dem Client nen Barcodescanner laufen, der seine Daten auf den Server übertragen soll. Also hab ich mit RdpClient-ActiveX ein Clienttool geschrieben, welches per CreateVirtualChannels einen Kanal zum Server aufbaut. Auf dem Server läuft ein Thread, der per WTSVirtualChannelRead liest, ob auf den Channel was geschrieben wurde und die Daten nötigenfalls übernimmt. Bei Dir wär das zwar die andere Richtung aber im wesentlichen ja dasselbe.
Marco Warm
TUO
TheUnknownOnes.net
  Mit Zitat antworten Zitat
marabu

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

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 20. Sep 2005, 10:00
Hallo Jens,

wenn du vor dem Probieren ein wenig Studieren möchtest - hier der passende Grundlagenartikel aus dem MSJ: klick

Grüße vom marabu
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#5

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 20. Sep 2005, 14:14
Ich lese mich da rein und werde mal ein paar Versuche starten.
Vermutlich werden dann noch ein paar Fragen kommen ....

Ich danke Euch erstmal für die Infos.


Schöne Grüße,
Jens

  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#6

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 20. Sep 2005, 23:00
So, jetzt gehts los ... ich und API und obendrauf noch C Syntax. Da habe ich mir was vorgenommen

Zum Verständnis für Diejenigen, die auch einmal Daten zwischen Terminalserver und Terminalclient über Virtual Channels austauschen müssen, hier einmal knapp die grobe Funktion.

Die um VirtuelChannels nutzen zu können, wird auf den Terminalclient eine DLL als Addin an den Terminalclient gebunden. Diese DLL wird dem Terminalclient über einen RegistryKey bekanntgegeben und geladen, sobald eine Terminalsitzung aufgebaut wird. Der Client initialisiert den/die Virtual Channel. Auf den Terminalserver läuft eine kleine Applikation in der Clientsitzung, die den Virtual Channel öffnet.
Sobald ein Kanal steht können beide Seiten (Server-Applikation und Client-Addin) mit WTSVirtualChannelRead / WTSVirtualChannelWrite über diesen Kanal Daten austauschen. Insgesamt können bis max. 28 VChannels geöffnet werden.


Jetzt zu meinem ersten Problem:

Um das Terminalserverhandle herauszufinden (benötigt um mit WTSEnumerateSessions die aktuellen SitzungsID zu ermitteln) werden die beiden DLL-Funktionen WTSOpenServer und WTSCloseServer aus der wtsapi32.dll benötigt.
Die DLL habe ich dynamisch geladen und die DLL Funktionen in der Server-Applikation wie folgt zugewiesen:

Delphi-Quellcode:
type
  TWTSAPI32_WTSOpenServer=function (pServerName:Pointer):THandle; stdcall;
  TWTSAPI32_WTSCloseServer=procedure (hServer:Pointer); stdcall;
  ...
private
  WTSAPI32_WTSOpenServer:TWTSAPI32_WTSOpenServer;
  WTSAPI32_WTSCloseServer:TWTSAPI32_WTSCloseServer;

var

implementation
...
  @WTSAPI32_WTSOpenServer := GetProcaddress(HDL_WTSAPI32_DLL,pchar('WTSOpenServer'));
  if @WTSAPI32_WTSOpenServer = NIL then
  begin
    log.lines.add('WTSAPI32.DLL - Funktion WTSOpenServer wurde nicht gefunden oder ist falsch deklariert');
  end
  else begin
    log.lines.add('WTSAPI32.DLL - Funktion WTSOpenServer erfolgreich initialisiert');
  end;

  @WTSAPI32_WTSCloseServer := GetProcaddress(HDL_WTSAPI32_DLL,pchar('WTSCloseServer'));
  if @WTSAPI32_WTSCloseServer = NIL then
  begin
    log.lines.add('WTSAPI32.DLL - Prozedur WTSCloseServer wurde nicht gefunden oder ist falsch deklariert');
  end
  else begin
    log.lines.add('WTSAPI32.DLL - Prozedur WTSCloseServer erfolgreich initialisiert');
  end;
...
WTSCloseServer wird erfolgreich zugewiesen, WTSOpenServer jedoch nicht.

Laut MSDN ist WTSOpenServer so deklariert...

Delphi-Quellcode:
HANDLE WTSOpenServer(
  LPTSTR pServerName
);
Was ist hieran falsch ?
TWTSAPI32_WTSOpenServer=function (pServerName:Pointer):THandle; stdcall; Schöne Grüße,
Jens
  Mit Zitat antworten Zitat
Benutzerbild von x000x
x000x

Registriert seit: 21. Jan 2004
Ort: Bei Hamburg
308 Beiträge
 
Delphi XE2 Professional
 
#7

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 20. Sep 2005, 23:48
Moin moin,
Zitat von jensw_2000:
Delphi-Quellcode:
type
...
  @WTSAPI32_WTSOpenServer := GetProcaddress(HDL_WTSAPI32_DLL,pchar('WTSOpenServer'));
...
WTSCloseServer wird erfolgreich zugewiesen, WTSOpenServer jedoch nicht.
probiers mal mit
Delphi-Quellcode:
type
...
  @WTSAPI32_WTSOpenServer := GetProcaddress(HDL_WTSAPI32_DLL,pchar('WTSOpenServerA'));
...
Zitat von MSDN:
implemented as WTSOpenServerW (Unicode) and WTSOpenServerA (ANSI).
Peter
-= Gruss Peter =-
-= alias x000x =-
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#8

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 20. Sep 2005, 23:54
Genial, das wars ...
Danke
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#9

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 21. Sep 2005, 20:26
Hallo,
Hier ist mein nächstes Problem, an dem ich nun schon fast den ganzen Tag experimentiere.

WTSEnumerateSessions liefert bei korrektem Aufruf ein Array (?) of WTS_SESSION_INFO und die Anzahl der in dem Array (?) enthantenen Elemente zurück.

Delphi-Quellcode:
typedef struct _WTS_SESSION_INFO
  {  DWORD SessionId;  LPTSTR pWinStationName;  WTS_CONNECTSTATE_CLASS State; } 
  WTS_SESSION_INFO, PWTS_SESSION_INFO;

typedef enum _WTS_CONNECTSTATE_CLASS
{
  WTSActive,
  WTSConnected,
  WTSConnectQuery,
  WTSShadow,
  WTSDisconnected,
  WTSIdle,
  WTSListen,
  WTSReset,
  WTSDown,
  WTSInit
}
 WTS_CONNECTSTATE_CLASS;


BOOL WTSEnumerateSessions(
  HANDLE hServer,
  DWORD Reserved,
  DWORD Version,
  PWTS_SESSION_INFO* ppSessionInfo,
  DWORD* pCount
);
Nachdem ich hier ein paar Infos gefunden habe, sieht meine derzeitige Umsetzung wie folgt aus:

Delphi-Quellcode:
type
  WTS_CONNECTSTATE_CLASS = LongInt;
const
  WTSActive = WTS_CONNECTSTATE_CLASS(1);
  WTSConnected = WTS_CONNECTSTATE_CLASS(2);
  WTSConnectQuery = WTS_CONNECTSTATE_CLASS(3);
  WTSShadow = WTS_CONNECTSTATE_CLASS(4);
  WTSDisconnected = WTS_CONNECTSTATE_CLASS(5);
  WTSIdle = WTS_CONNECTSTATE_CLASS(6);
  WTSListen = WTS_CONNECTSTATE_CLASS(7);
  WTSReset = WTS_CONNECTSTATE_CLASS(8);
  WTSDown = WTS_CONNECTSTATE_CLASS(9);
  WTSInit = WTS_CONNECTSTATE_CLASS(10);

type
  _WTS_SESSION_INFO = record
    SessionId: DWORD;
    pWinStationName: LPTSTR;
    State: WTS_CONNECTSTATE_CLASS;
  end;
  WTS_SESSION_INFO = _WTS_SESSION_INFO;
  PWTS_SESSION_INFO = ^_WTS_SESSION_INFO;

type
  TWTSAPI32_WTSEnumerateSessions = function(hServer: THandle; Reserved: DWORD; Version: DWORD; ppSessionInfo: pWTS_SESSION_INFO; pCount: pDWORD): BOOL; stdcall;
  TWTSAPI32_WTSFreeMemory = procedure(pMemory: Pointer); // zum Freigben des Speichers von pPWTS_SESSION_INFO



Type
  TMain = Class(TForm) ...
  ...
  private
    // Rückgabewerte von WTSEnumerateSessions
    ARR_WTS_SESSION_INFO : ARRAY OF WTS_SESSION_INFO;
    pPWTS_SESSION_INFO : Pointer = @ARR_WTS_SESSION_INFO;

    WTS_SESSION_COUNT : Integer;
    pCount : Pointer = @WTS_SESSION_COUNT;
    
    
    WTSAPI32_WTSEnumerateSessions: TWTSAPI32_WTSEnumerateSessions;
    WTSAPI32_WTSFreeMemory: TWTSAPI32_WTSFreeMemory;
  


...
...
implementation

...
  if NOT WTSAPI32_WTSEnumerateSessions(WTS_Server_Handle, 0, 1, pPWTS_SESSION_INFO, pCount) then
  begin
    log.Lines.Add('TerminalserverSessions konnten nicht ausgelesen werden');
    FreeLibrary(HDL_WTSAPI32_DLL);
    HDL_WTSAPI32_DLL := 0;
    WTSAPI32_WTSFreeMemory(pPWTS_SESSION_INFO);
    exit;
  end
  else begin
    log.Lines.Add(' TerminalserverSessions wurden ermittelt');
    WTSAPI32_WTSFreeMemory(pPWTS_SESSION_INFO);
  end;

...
Leider ist das Ergebnis von WTSAPI32_WTSEnumerateSessions immer false
Der Aufruf von WTSAPI32_WTSFreeMemory(pPWTS_SESSION_INFO) bringt eine AV, wahrscheinlich weil der Pointer ins Nirvana zeigt ...

[EDIT]

Ich habe eben noch ein GetLastError eingebaut ...
Unter Win2000 Server (aus einer Terminalsession) bekomme ich als Fehler "Klasse nicht vorhanden" und unter WinXP Pro "Zugriff verweigert".
Das "Zugriff verweigert" kommt sicher daher, das ich unter WinXP keine Möglichkeit finde, das TS Recht "Query Information" zu setzen ...

[/EDIT]


Ich brauche Hilfe bei der Übersetzung der C Header und Typen ...
Wäre wirklich nett, wenn ihr mir dabei helfen würdet.

Danke und schöne Grüße,
Jens
  Mit Zitat antworten Zitat
Benutzerbild von x000x
x000x

Registriert seit: 21. Jan 2004
Ort: Bei Hamburg
308 Beiträge
 
Delphi XE2 Professional
 
#10

Re: Datenaustausch (Message o.Ä.) von Terminalserver an Clie

  Alt 22. Sep 2005, 00:33
Moin moin,
Delphi-Quellcode:
//..
type
   TWtsConnectStateClass = (WTSActive, WTSConnected, WTSConnectQuery,
                            WTSShadow, WTSDisconnected, WTSIdle, WTSListen,
                            WTSReset, WTSDown, WTSInit);
type
   PWtsSessionInfo = ^TWtsSessionInfo;
   _WTS_SESSION_INFOA = packed record
      SessionId : DWORD;
      pWinStationName : LPTSTR;
      State : TWtsConnectStateClass;
   end;
   TWtsSessionInfo = _WTS_SESSION_INFOA;

const
   WTS_CURRENT_SERVER_HANDLE = 0;

type
  TFNWtsEnumerateSessions = function (hServer: THandle; Reserved: DWORD;
                                    Version: DWORD; out ppSessionInfo: PWtsSessionInfo;
                                    out pCount: PDWORD): BOOL; stdcall;
  TFNWtsFreeMemory = procedure(pMemory: Pointer); stdcall;

//..

function ConStateToStr(const conState: TWTSConnectStateClass): String;
begin
   case conState of
      WTSActive : Result := 'WTSActive';
      WTSConnected : Result := 'WTSConnected';
      WTSConnectQuery : Result := 'WTSConnectQuery';
      WTSShadow : Result := 'WTSShadow';
      WTSDisconnected : Result := 'WTSDisconnected';
      WTSIdle : Result := 'WTSIdle';
      WTSListen : Result := 'WTSListen';
      WTSReset : Result := 'WTSReset';
      WTSDown : Result := 'WTSDown';
      WTSInit : Result := 'WTSInit';
   else
      Result := 'Unknown';
   end;
end;

//..

var count : PDWord;
    SessionInfo : PWtsSessionInfo;
begin
   try
      Win32Check(WtsEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, SessionInfo, count));
      ShowMessage('State=' + ConStateToStr(SessionInfo.State) + #13#10 +
                  'SessionID=' + IntToStr(SessionInfo.SessionId) + #13#10 +
                  'pWinStationName=' + SessionInfo.pWinStationName);
      WtsFreeMemory(SessionInfo);
   except
      On E: Exception do
           //..
   end;
end;
so würde ich es machen, aber keine Garantie dafür. Vielleicht fehlt bei dir ja auch nur das stdcall bei
der Typedeklaration von TWTSAPI32_WTSFreeMemory.

Sprech evtl. mal Olli per PN an,
der hat da eher nen Plan davon und hilft immer gerne...
(Bestimmt auch noch andere, bei Olli kann ich aber aus Erfahrung sprechen)
Peter
-= Gruss Peter =-
-= alias x000x =-
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

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

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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:58 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