Benutzer auf Terminalserver abfragen/Probleme mit query.exe

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Fortender.

    Benutzer auf Terminalserver abfragen/Probleme mit query.exe

    Hallo,

    wir arbeiten bei uns in der Firma mit einer Anwendung, welche auf einem Terminalserver liegt. Nun kommt es leider ab und an mal vor, das der Nutzer sich nicht ordentlich anmeldet. Die Verbindung bleibt also bestehen, ein erneutes Verbinden ist nicht möglich.
    Ich wollte also ein kleines Programm schreiben, womit sich der Benutzer selber vom Terminalserver abmelden kann falls es mal Probleme gibt (gerade in Zeiten wo die technische Betriebsführung nicht erreichbar ist). Unter DOS kann ich ja mit query session /server:servername meine ID auf dem Server ermitteln und mit logoff die Verbindung trennen. Das traue ich unseren Leuten allerdings nicht zu. Für VB habe ich bisher kein passendes Äquivalent gefunden. Also habe wollte ich mittels Process den Dos-Befehl verwenden und das Ergebnis auslesen.

    Quellcode

    1. Dim oInfo As System.Diagnostics.ProcessStartInfo = New System.Diagnostics.ProcessStartInfo("cmd", "query session /server:servername")
    2. oInfo.UseShellExecute = False
    3. oInfo.ErrorDialog = False
    4. oInfo.CreateNoWindow = True
    5. oInfo.RedirectStandardOutput = False
    6. Dim p As Process = System.Diagnostics.Process.Start(oInfo)
    7. Dim oReader As System.IO.StreamReader = p.StandardOutput
    8. TextBox1.Text = oReader.ReadToEnd()
    9. oReader.Close()


    Im Dos-Fenster steht, das der Befehl "query" nicht bekannt ist.
    Also wollte ich den Umweg gehen und schreibe eine Batch-Datei welche den Befehl enthält und das Ergebnis in eine Textdatei schreibt. Führe ich die Batch Datei mit Process.Start aus bekomme ich die gleiche Fehlermeldung. Führe ich sie händig aus klappt alles. Hat jemand eine Idee woran das liegen könnte oder vielleicht ein VB Äquivalent zum Dos Befehl?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „AndPod“ ()

    Du kannst query direkt ausführen, dafür brauchst du keine cmd: New System.Diagnostics.ProcessStartInfo("query", "session /server:servername")
    @slice
    Das klappt leider mit (meinem oben aufgeführten Code) nicht, da kommt die Meldung das die Datei nicht gefunden wurde. Selbst wenn ich den kompletten Pfad angebe:
    C:\Windows\System32\query.exe

    Ich habe an anderer Stelle übrigens gelesen das es ein 32/64Bit Problem sein könnte. Wie oben geschrieben hatte ich es auch versucht, das ganze in eine Batch-Datei auszulagern und das Ergebnis in eine Textdatei schreibe welche ich dann auslese. Wenn ich die Batch-Datei mittels Windows Explorer starte läuft diese auch, starte ich sie über meine Anwendung oder über den z.B. FreeCommander klappt es nicht mehr. Hängt also irgendwie damit zusammen, wie der Befehl aufgerufen wird.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „AndPod“ ()

    @slice
    Ich vermute mal, ich soll da das Verzeichnis der query.exe hinterlegen? Also "c:\Windows\System32\"? Das Funktioniert auch nicht, die Fehlermeldung bleibt die gleiche.

    Edit: Hier der Code wie er aktuell aussieh, der Fehler tritt in der letzten Zeile auf:

    VB.NET-Quellcode

    1. Dim oInfo As New System.Diagnostics.ProcessStartInfo
    2. oInfo.FileName = "query.exe"
    3. oInfo.WorkingDirectory = "c:\windows\system32\"
    4. oInfo.Arguments = "session /server:xxx"
    5. oInfo.UseShellExecute = False
    6. oInfo.ErrorDialog = False
    7. oInfo.CreateNoWindow = True
    8. oInfo.RedirectStandardOutput = True
    9. Dim p As Process = System.Diagnostics.Process.Start(oInfo)


    Und hier der entsprechende Fehler:

    System.ComponentModel.Win32Exception wurde nicht behandelt.
    ErrorCode=-2147467259
    HResult=-2147467259
    Message=Das System kann die angegebene Datei nicht finden
    NativeErrorCode=2
    Source=System

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „AndPod“ ()

    @petaod & @Facebamm
    Die Varianten hatte ich ja auch schon durch (siehe Post 5). Die Datei ist auf jeden Fall da. Ich hatte ja schon im Post 5 angemerkt, dass das wohl daran liegt, wie der Befehl aufgerufen wird. In einer Batch-Datei über den Windows Explorer gestartet läuft der Befehl. Über die Anwendung FreeCommander gestartet wiederum nicht.
    Ich nehme an, dass du deine Anwendung auf einem 64-Bit Windows ausführst und dir daher die automatische Ordnerumleitung von System32 auf SysWow64 Probleme bereitet. Die "query.exe" liegt da nämlich nicht drin.
    Man kann Windows allerdings per WinAPI mitteilen, dass man gerne auf dem aktuellen Thread auf die automatische Ordnerumleitung verzichten möchte. Realisieren kannst du das über Wow64DisableWow64FsRedirection und Wow64RevertWow64FsRedirection
    Kleines ungetestetes unvollständiges Beispiel:

    VB.NET-Quellcode

    1. Declare Function Wow64DisableWow64FsRedirection Lib "kernel32.dll" (ByRef ptr As IntPtr) As Boolean
    2. Declare Function Wow64RevertWow64FsRedirection Lib "kernel32.dll" (ByRef ptr As IntPtr) As Boolean
    3. Dim addressOrHostname As String = "[address]"
    4. Dim handle = New IntPtr()
    5. Wow64DisableWow64FsRedirection(handle) 'Ordnerumleitung deaktivieren
    6. Dim startInfo = New ProcessStartInfo With
    7. {
    8. .RedirectStandardOutput = True,
    9. .RedirectStandardError = True,
    10. .CreateNoWindow = True,
    11. .FileName = "cmd.exe",
    12. .Arguments = $"/C ""query user /server:{addressOrHostname}"""
    13. }
    14. Using proc As Process = Process.Start(startInfo)
    15. proc.WaitForExit()
    16. Using outputReader = proc.StandardOutput
    17. ' Parse input
    18. End Using
    19. Using errorReader = proc.StandardError
    20. ' Parse error
    21. End Using
    22. End Using
    23. Wow64RevertWow64FsRedirection(handle) 'Ordnerumleitung reaktivieren

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Fortender“ ()

    das kann man ganz leicht herausfinden @Fortender, aber ich ganz der meinung das es daran nicht liegt

    C#-Quellcode

    1. Console.WriteLine("Is64BitOperatingSystem: {0}", Environment.Is64BitOperatingSystem);
    2. Console.WriteLine("Is64BitProcess: {0}", Environment.Is64BitProcess);
    3. Console.WriteLine("SystemDirectory: {0}", Environment.SystemDirectory);

    der output sollte so aussehen

    Quellcode

    1. Is64BitOperatingSystem: True
    2. Is64BitProcess: True
    3. SystemDirectory: C:\WINDOWS\system32

    Facebamm schrieb:

    das kann man ganz leicht herausfinden <a href="https://www.vb-paradise.de/index.php/User/3401-Fortender/">@Fortender</a>, aber ich ganz der meinung das es daran nicht liegt
    C#-Quellcode (3 Zeilen)
    der output sollte so aussehen
    Quellcode (3 Zeilen)

    Die Weiterleitung findet wohl betriebssystemintern statt. Logischerweise ist der System32-Ordner aufgrund von Kompatibilitätsgründen sowohl für 32-bit, als auch für 64-bit Anwendungen adressierbar. Bei AnyCPU-Kompilationen auf 64-Bit Systemen findet allerdings die oben angesprochene Umleitung statt. Natürlich gibt dir Environment.SystemDirectory den System32-Ordner zurück. Das hat aber rein gar nichts mit dem oben genannten zu tun.
    Kannst ja mal die Kommandozeile über dein Programm aufrufen unter Angabe des System32-Ordners als WorkingDirectory und dort dann dir query* ausführen. Du wirst lediglich eine Query.dll finden ;)

    AndPod schrieb:

    Ja, ich arbeite mit Windows 10 64 Bit.
    <a href="https://www.vb-paradise.de/index.php/User/3401-Fortender/">@Fortender</a>
    Dein Code funktioniert prima, man muss nur noch VB.NET-Quellcode (1 Zeile) mit einbauen. Vielen Dank hierfür <img src="https://www.vb-paradise.de/wcf/images/smilies/smile.png" alt=":)" />

    <a href="https://www.vb-paradise.de/index.php/User/23867-Facebamm/">@Facebamm</a>
    Bei mir sieht es so aus:
    Zitat: „Is64BitOperatingSystem: True
    Is64BitProcess:…

    An UseShellExecute = False habe ich nicht gedacht. Der Code ist aus dem Kopf (deshalb auch das minderwertige Formatting). Freut mich aber, dass ich dir helfen konnte :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Fortender“ ()