Announcement

Collapse
No announcement yet.

Werte aus DOS-Box unter NT/2000 grabben????

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Werte aus DOS-Box unter NT/2000 grabben????

    Wie kann ich, Werte aus der DOS-Box (cmd.exe) grabben? Ich meine damit, wenn ich zB 'NET SEND "Administrator" "Hallo"' benutze, dann gibt NET SEND doch eine Text-Zeile zurück ob der Benutzer die Nachricht bekommen hat od. nicht. Genau diesen Text möchte ich grabben, habe es bis jetzt aber noch nie geschafft.

    Hoffe hier kann mir geholfen werden!

    Thomas

  • #2
    Hallo,

    wenn die im Fenster der Eingabeaufforderung (Console alias "DOS-Fenster") ausgeführte Anwendung vom eigenen Programm startet wird (d.h. wenn das Prozess-Handle bekannt ist), kann die eigene Anwendung direkt den Inhalt der Console auslesen. Das folgende Beispiel kopiert den Inhalt des "DOS-Fensters" in eine TMemo-Instanz im Formular:
    <pre>
    procedure TFormMain.btnGrabClick(Sender: TObject);
    var
    aDest : TCoord;
    aCSBI : TConsoleScreenBufferInfo;
    i, j : integer;
    sLineBuff : String;
    szOemChar : array[0..254] of Char;
    pGrabBuff : pcInfo;
    begin
    btnGrab.Enabled := False;
    aDest.X := 0;
    aDest.Y := 0;
    try
    // Eigenschaften (Breite+Höhe) des Consolenfensters auslesen
    GetConsoleScreenBufferInfo(hConsole, aCSBI);
    // Platz für den Zeilenpuffer reservieren
    SetLength(sLineBuff, aCSBI.dwMaximumWindowSize.X + 1);
    // Platz für den Consolenpuffer reservieren
    // (= Breite * Höhe * Größe von TCharInfo)
    with aCSBI.dwMaximumWindowSize do
    GetMem(pGrabBuff, X * Y * SizeOf(TCharInfo));
    try
    // Inhalt des Consolen-Fensters in den Puffer einlesen
    with aCSBI do
    ReadConsoleOutput(hConsole, pGrabBuff,
    dwMaximumWindowSize, aDest, srWindow);
    // Daten aus dem Puffer in die TMemo-Instanz einsetzen
    Memo1.Clear;
    with aCSBI.dwMaximumWindowSize do begin
    // Inhalt des Consolenfensters Zeilenweise auslesen
    for i := 0 to Y - 1 do begin
    // Zeilenpuffer leeren
    sLineBuff := '';
    // alle Zeichen dieser Zeile in den Zeilenpuffer kopieren
    for j := 1 to X do
    sLineBuff := sLineBuff + pGrabBuff^[i * X + j].AsciiChar;
    // Zeichensatz (OEM) nach ANSI konvertieren
    OemToChar(PChar(sLineBuff), szOemChar);
    // gefüllten Zeilenpuffer in die TMemo-Instanz einsetzen
    Memo1.Lines.Add(szOemChar);
    end;
    end;
    StatBar.Panels[1].Text := Format('%d x %d Zeichen',
    [aCSBI.dwMaximumWindowSize.X,
    aCSBI.dwMaximumWindowSize.Y]);
    finally
    Freemem(pGrabBuff);
    end;
    finally
    btnGrab.Enabled := true;
    end;
    end;
    </pre>
    Weitere Infos sind im FORUM über die Suche nach der Zeichenkette "ReadConsoleOutput" zu finden

    Comment


    • #3
      Ich glaube das ganze Grabben kannst Du Dir sparen und sogar noch ein paar nette Features mehr nutzen, wenn Du die API-FUnktion direkt benutzt.
      Ich habe Dir mal eben eine Unit dafür geschrieben:

      <pre>
      unit NetSend;

      interface

      uses
      Windows;

      const
      netapi = 'netapi32.dll';

      type
      LPBYTE = PByte;
      NET_API_STATUS = DWord;

      const
      // success
      NERR_Success = 0;
      // Base address of error codes
      NERR_BASE = 2100;
      // A general network error occurred.
      NERR_NetworkError = NERR_BASE + 36;
      // The user name could not be found.
      NERR_NameNotFound = NERR_BASE + 173;
      // The user does not have access to the requested information.
      // ERROR_ACCESS_DENIED - declared in Windows.pas (= 5)
      // This network request is not supported.
      // ERROR_NOT_SUPPORTED - declared in Windows.pas (=50)
      // The specified parameter is invalid.
      // ERROR_INVALID_PARAMETER - declared in Windows.pas (=87)

      function NetMessageBufferSend(servername, msgname, fromname: LPCWSTR;
      buf: LPBYTE; buflen: DWORD
      ): NET_API_STATUS; stdcall;

      function NetSendMsg(serv, name, text: string): NET_API_STATUS;

      implementation

      function NetMessageBufferSend; external netapi name 'NetMessageBufferSend';

      // serv = name of the remote server on which the function is to execute
      // (The string must begin with \\ or empty ('') for local computer
      // (you need some privileges to do this on other machines
      // name = the message alias to which the message should be sent
      // text = string that contains the message text (multiline is no problem)
      function NetSendMsg(serv, name, text: string): NET_API_STATUS;
      var
      msgserv: PWideChar;
      servlen: Cardinal;
      msgname: PWideChar;
      namelen: Cardinal;
      msgtext: PWideChar;
      textlen: Cardinal;
      begin
      Result := ERROR_INVALID_PARAMETER;
      servlen := 2 * (Length(serv) + 1);
      namelen := 2 * (Length(name) + 1);
      textlen := 2 * (Length(text) + 1);
      if (servlen > 2)
      then msgserv := GetMemory(servlen)
      else msgserv := nil;
      msgname := GetMemory(namelen);
      msgtext := GetMemory(textlen);
      if Assigned(msgname) and Assigned(msgtext) then try
      if Assigned(msgserv) then StringToWideChar(serv, msgserv, servlen div 2);
      StringToWideChar(name, msgname, namelen div 2);
      StringToWideChar(text, msgtext, textlen div 2);
      Result := NetMessageBufferSend(msgserv, msgname, nil, PByte(msgtext), textlen);
      finally end;
      if Assigned(msgtext) then FreeMemory(msgtext);
      if Assigned(msgname) then FreeMemory(msgname);
      if Assigned(msgserv) then FreeMemory(msgserv);
      end;

      end.
      </pre>

      wenn Du eine Nachricht an alle in einer Domäne schicken willst, dann gibst Du als Namen einfach 'EINE_DOMAENE*' an.
      Wie schon in der Unit beschrieben, uebergibst Du einfach einen Leerstring als Server, wenn Du die Nachricht von Deinem Rechner schicken willst. Denn es bedarf einer Rechte, um das NetSend auf einem anderen Rechner auszuführen. Aber es ist kein Problem, zB kann ich problemlos eine Nachricht von einer Workstation zur anderen schicken, ohne, dass jemals mein Name auftaucht - sondern es ist einfach so, als ob die Workstation selbst NetSend aufgerufen haette.

      Gruss Nicosch

      delphi rulz!
      &#10

      Comment

      Working...
      X