@OP: Das angesprochene threading von __blackjack__ bezieht sich auf Race-Conditions. Also wenn zwei oder mehr Threads gegeneinander kämpfen. Der eine Thread kann z.B. eine Variable zuweisen, während der andere Thread noch einen alten Wert ausgelesen hat mit diesem weiter arbeitet und dann ggf. wieder eine Zuweisung macht. Spätestens da hat man ein Chaos und es ist sehr schwer nachzuvollziehen, wenn der Code komplexer wird. Das ist einer der Gründe, wieso es so schwierig ist Threading richtig zu implementieren.
Ping bleibt nicht hängen, sofern man einen Timeout angibt. Ich wies auch nochmal drauf hin, dass der Syntax unter Windows etwas anders ist.
Dort wird es aber auch einen Parameter für den timeout geben.
Wenn man sich nicht auf das Betriebssystem verlassen will/kann, könnte man eine Implementierung in Python nehmen.
Da hat man aber das Problem, dass man erhöhte Rechte benötigt. Unter Linux ist das so und unter Windows schätze ich mal auch.
Das wäre ziemlich doof das Programm mit Adminstrator-Rechten auszuführen.
Zum Threading:
Wenn ping nur einmal ausgeführt wird, gibt es auch nur einen Thread, der den Call macht. Also nur eine Zuweisun. Um zu verhindern, dass zur Laufzeit des Threads kein weiterer gestartet werden kann.
Ja, man könnte das sogar so toll machen, dass man den Thread vorzeitig beenden kann.
Hier mal eine erweiterte Version:
Code: Alles auswählen
from tkinter import Tk, Button
from subprocess import call, PIPE
from threading import Thread, Event
PING_EVENT = Event()
def ping(buttons):
"""
Startet einen Daemon Thread und pingt alle Rechner an.
"""
if not PING_EVENT.is_set():
PING_EVENT.set()
thread = Thread(target=_ping, args=[buttons], daemon=True)
thread.start()
else:
print('Ping is currently executed.')
def _ping(buttons):
"""
Diese Funktion wird als Thread gestartet.
Es wird jeder Rechner angepingt und die Buttons werden eingefärbt.
"""
for button, host in buttons:
# button ist die Referenz zum button
# host ist der Hostname bzw. die IP Adresse
command = ['ping', '-c', '1', '-W', '1', host]
# Ping Befehl ist unter Windows etwas anders
# Damit das funktioniert, muss er angepasst werden
if call(command, stdout=PIPE, stderr=PIPE) == 0:
button.config(bg='green')
else:
button.config(bg='red')
PING_EVENT.clear()
def shutdown(host):
"""
Hier den code ergänzen, um Windows-PCs herunter zu fahren
Aktuell findet nur eine Ausgabe in der Konsole statt und sonst
passiert nichts.
"""
print(f'shutdown -R {host}')
def app(names_or_ips):
"""
Mit der funktion wird die GUI gestartet und alles weitere konfiguriert.
"""
root = Tk()
root.title('Windows Shutdown Tool')
buttons = []
# die Liste buttons soll nach dem Durchlauf der Schleife jeweils den
# Button als Objekt und die IP als string beinhalten
for row, host in enumerate(names_or_ips):
button = Button(root, text=host, command=lambda: shutdown(host))
button.grid(row=row, column=0)
buttons.append((button, host))
# row == letzter wert
row += 1
Button(root, text='Ping', command=lambda: ping(buttons)).grid(row=row, column=0)
row += 1 # wieder um einen hochzählen, um in der nächsten Zeile zu landen.
Button(root, text='Quit', command=root.destroy).grid(row=row, column=0)
root.after(500, ping, buttons) # nach 500 ms die Hosts anpingen
root.mainloop()
if __name__ == '__main__':
# die Hosts können Namen oder IP-Adressen sein.
hosts = ['192.168.0.1', '192.168.0.2', '192.168.0.3']
# hier wird die GUI gestartet.
app(hosts)
Falls du eine bessere Lösung kennst, dann poste sie einfach als Code. Darüber diskutieren kann man, wenn du ein Snippet gepostet hast.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server