Feststellen, ob Netzwerkkabel gezogen wurde?
Hi@all,
hab' mal ne kleine Frage, ich denke die meisten wissen, wie man sowas programmiert. Und zwar Windows bemerkt es doch sofort, wenn ich das Netzwerkkabel rausziehe, wie kann ich programmieren, dass auch meine Delphi-Anwendung das feststellt? Bis jetzt hatte ich das immer so gemacht, dass die Clients einfach alle 2 Sekunden einen Ping losschicken, allerdings erhöht das den Traffic enorm und außerdem, wenn der Server mal ausfällt (bzw. überlastet ist), dann ist's vorbei mit dem Ping. Beim Ping brauche ich auch immer ein Gegenstück. Am Anfang dachte ich es geht, einen Ping an 127.0.0.1 zu schicken, aber das geht auch, wenn das Kabel nicht mehr drin steckt, war also keine gute Lösung. Habt ihr irgendeine Idee? |
dann ping doch einen anderen Rechner an. Wird zwar auch nicht viel nützen, aber es wäre Server-unabhängig. :mrgreen:
|
Ne, jetzt im Ernst, da muss es doch eine Möglichkeit geben.
Ich kann nicht 100 Rechner irgendwas anpingen lassen, das muss schon vernünftig programmiert sein. Gibt es sonst noch irgendeine Lösung? |
Zitat:
|
Zitat:
Ich möchte lediglich eine Komponente, die mir sagt, wann das Netzwerk- kabel rausgezogen wurde, mehr nicht! Dabei wäre es nicht schlecht, wenn ich einfach nichts anpingen müsste. Also, ich sag' euch jetzt mal, wozu das gut sein soll: Alle Computer sind bei uns mit dem Netzwerk verbunden. Da es aber immer Scherzkekse gibt, die die Kabel rausziehen, war meine Überlegung, ein Delphi-Programm zu programmieren, das den Computer ausschaltet, sobald das Kabel rausgezogen wird. Wenn ich jedoch bspw. einen Server anpinge und ich diesen neustarte, dann gehen alle Rechner aus, das will ich nicht, deswegen möchte ich es möglichst ohne Ping! Jetzt alles klar? Der andere Punkt ist, wenn der Traffic im Netzwerk sehr hoch ist, hat ein Ping zu lange Laufzeiten, deswegen ist das auch nicht günstig. Deshalb gibt es irgendeine Möglichkeit, wie Windows das macht, wenn das Kabel gezogen wird, das meine Delphi-Anwendung das auch merkt? |
Zitat:
Zitat:
|
Hallo,
ich denke, wir sollten nicht vorschnell urteilen. Die Ausgangsfrage wurde sachlich und vernünftig gestellt und ich sehe in der Thematik keine unmittelbare Problematik, welche einer Beantwortung dieser Frage im Wege stehen könnte. keep cool... :wink: |
Unter Umständen könntest Du versuchen, irgendwas mit den Windows-Sockets zu veranstalten; dort gibt es eine Funktion "WSAGetLastError", welche u.A. den Code "WSAENETDOWN" zurückliefert, welcher wie folgt beschrieben ist:
Zitat:
|
Zitat:
Leider kann ich eurer Diskussion nicht ganz folgen. Ich bin der Administrator dieses Netzes, was heißt entlassen, also momentan verstehe ich bloß Bahnhof, und zweitens kann man keinen Schüler der Schule verweisen, bloß weil er ein Kabel rausgezogen hat. Es ist einfach so, dass wir Administratoren immer wieder von Lehrern gerufen werden, weil man sich an einem Computer nicht anmelden kann. Und jedesmal kommen wir, schauen an der Rückseite, "ah ha, das Kabel ist mal wieder draußen"! Wenn das aber durch ein Programm verhindert wird, sprich der Computer geht immer aus, dann sagen wir den Lehrern einfach, wenn ein Rechner ausgeht, dann schaut nach dem Kabel und wir haben unsere Ruhe. Das ist in Kurzfassung eigentlich der Grund, warum ich so ein Kontrollprogramm brauche. Um genauer zu sein ist dieses "kleine" Programm nur ein Bestandteil eines viel größeren Programms und dieses kleine Problem mit dem Kabel ist das letzte, das ich noch habe. |
Dann kleb einen Zettel an jeden Arbeitsplatz wo erste Selbsthilfemaßnahmen draufstehen, wenn man sich nicht einloggen kann:
- Caps gedrück - NumLock aus - Netzwerkkabel gezogen |
Danke Daniel
Der Tip von Daniel hat mir schon weiter geholfen.
Die System Error Code Liste habe ich auch schon bei MSDN gefunden. Allerdings gibt mir die WSAGetLastError nur die Fehler zurück, die in meiner Anwendung auftreten. Wie kriege ich das hin, dass auch Fehler im System bemerkt werden? |
Zitat:
daran, dass es Bestandteil eines größeren Programms ist und da muss ich nunmal feststellen, ob das Kabel DRINSTECKT. Sagt mal, ist dann denn so schwer zu verstehen? :cry: Echt, im Ernst, ich brauch doch lediglich eine Funktion, die feststellt, ob das Kabel drinsteckt, das ist alles. Mehr nicht!!!! |
an deiner stelle würde ich einfach das mit dem Ping beibehalten.
wenn ein Client alle 15sec oder 30sec den server anpingt wird das jawohl nicht gleich den Server killen, oder? war auch mal vor 1nem jahr noch in'ner Schule und die Server sind eigentlich grausam unterbelastet. ich weiß leider nicht mehr wie die funktion heißt, aber es gibt glaube ich eine callback-funktion die eingehackte Programme über ein disconnect informiert. gib doch unter google mal: "+netzwerkverbindung +testen +delphi (+howto,+faq,tutorial)" ein. die stichwörter in der klammer nicht gleichzeitig... MfG Ben PS: Mehr fällt mir da imom auch nich ein... |
Zitat:
Zitat:
Zitat:
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
also bei mir gibt die funktion nicht wirklich diesen fehelercode zurück, wenn das netzwerkkabel gezogen wird !
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Vielleicht hilft Dir InternetGetConnectedState(Ex) weiter.
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
hey luckie dein ton is aber auch nich grad erste sahne.. vielleicht hat ihm der code doch nicht geholfen ?!
:warn: |
Zitat:
Genau dasselbe Problem hatte ich in meinem Heimnetz auch (dabei handelt es sich um meine eigenen Computer). Ich habe es aber damals nicht lösen können. Die Sache mit dem Ping war auch nicht möglich da in einem Netz mit 2 PCs öfters auch nur einer eingeschaltet ist. In der Code-Lib hat Daniel B mal einen Code mit GetSystemMetrics gepostet, mit dem man feststellen kann ob irgendeine Netzwerkverbindung hergestellt ist. Möglicherweise liefert die Funktion dann false zurück, wenn das Netzwerkkabel gezogen wurde. Das sieht so aus:
Delphi-Quellcode:
function IsNetworkConnected: Boolean;
begin if GetSystemMetrics(SM_NETWORK) and $01 = $01 then begin Result := True; end else begin Result := False; end; end; |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
und den code noch etwas vereinfacht:
Delphi-Quellcode:
gruss,
function IsNetworkConnected: Boolean;
begin Result := (GetSystemMetrics(SM_NETWORK) and $01) = $01; end; iaby |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Hey ist ja herrlich dass das noch ein Thema wird. Ich musste mich auch damit auseinander setzen.
Ich kann dir einige Informationen dazu geben. Zuerst einmal erhält Windows vom NDIS eine Nachricht wenn Kabel ausgesteckt worden ist (Daher auch die Meldung unten in der Taskbar). So wie fängt man sowas ab. Auf der NDIS seite hab ich dann einen C Code gefunden der mir ein bissel geholfen hat aber wiederum auch nicht... (zu wenig kentnisse in C vielleicht würde es klappen wenn ich mich jetzt wieder einlese) Aber ich habs dann doch noch gelöst über einen anderen unsauberen weg. Das schreib ich aber nachher nach der Besprechung wo ich grad hingezwungen werde... :-) MfG Kasoft |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
jo bitte poste doch mal deinen unsauberen weg !
kannst du auich mal den link zu dem C code posten ?? evtl kann der weiterhelfen ! |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Vielleicht hilft dir das ja (Das sollte die NDSI Seite sein): http://www.ndis.com/code_snippets/default.htm
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
So jetzt endlich aus dieser absolut langweiligen Sitzung raus...
Also die ganze Geschichte mit Netzwerkkabel raus rein läuft eigentlich über die MediaSense API. Den Link zu dem C Code hat dir ja schon der Moritz geschickt. Man sollte sich im klaren sein das MediaSense erst seit Windows 2000 existiert. (NDIS 5) Nach langem suchen und studieren der API hab ich mich dann doch beschlossen das alles komplett anders zu machen :-) . Ihr dürft raten :-) die supertolle wunderschöne fehlerlose Windows Registry hat nen Schlüssel in der sich beim einstecken und austecken ein Wert ändert :-) Ich poste mal den Code den ich damals zusammengefriemelt hab. Also ohne Garantie as funktionstüchtigkeit etc... Rückmeldungen wären schön da ich knapp 2 Monate mit der SenseAPI mich rumgeschlagen hab bevor ich dann doch zu dieser unüblichen Lösung kam...
Delphi-Quellcode:
So also macht euch mal her über den Code ;-)function NetworkConnect : Boolean; var reg : TRegistry; i : Integer; NetworkCards : String; begin result := false; reg := TRegistry.Create(KEY_READ); reg.RootKey := HKEY_LOCAL_MACHINE; for i := 0 to 15 do //Mehr als 15 Netzwerkkarten sollte kein normaler Rechner haben... if reg.KeyExists('\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\' +inttostr(i)) = true then begin reg.OpenKey('\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\' +inttostr(i),false); NetworkCards := reg.ReadString('ServiceName'); break; end; if NetworkCards <> '' then begin reg.OpenKey('\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\'+NetworkCards,false); if reg.ReadString('DHCPDomain') <> '' then result := true else result := false; end; reg.Free; end; MfG Kasoft P.S.: Ich danke unsererm VB Programmierer aus unserer Abteilung für seine Supergeniale unterstützung bei dem Problem ;-) Danke Thomas! |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
also bei mir unter winXP funzt dieser Code nicht ! er gibt immer false zurück !
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
schau mal in der Registry ob die Sachen existieren.
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
was ich noch vergessen hab. Windows braucht eine kleine Weile bis er bemerkt das Kabel nicht
da ist. Also nicht rausziehen gleich anklicken und dann sagen geht net raus :-) |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
kommt auf die Version an, meins (Windows XP) erkennt sofort, wenn ich ds Kabel ziehe.
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Hab daheim WinXP. Da kann es verspätet kommen muss aber nicht. Im Geschäft
Win2k und es reagiert auch nicht schneller/langsamer als mein XP... |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Tach,
aslo, ich hab mich mal damit beschäftigt, es passiert einiges in der Registry. Ich hab leider keine Zeit das auszuwerten, aber das würde ich auf jeden Fall mal als Ansatz verfolgen (Mittels RegMon). Ansonsten wäre könntest du es evtl. damit lösen, wenn du alles 5 Sekunden die Netzwerk-IP prüfst, und sobald die 0 bzw. 0.0.0.0 ist dan PC ausschalten. Das wäre glaube ich das effektivste, denn sobald das Kabel steckt hat dein PC eine IP. (Zumindest wenn er so konifguriert ist...aber davon gehe ich bei euren Schulrechnern mal aus) Gruß |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Zitat:
Allerdings kann der Rechner (u.A. gerade in Schulnetzen bei je einem Subnet pro Klassenraum) statisch konfiguriert sei (macht zum Teil bei überschaubaren Subnets durchaus Sinn) - und dann hat der die IP sowieso immer, ob nun Kabel oder nicht. |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
wenn mein Rechner nicht mit dem Switch verbunden ist, so bekomm ich als IP immer die localhost-adresse. Sobald eine Verbindung besteht hat er die IP, wie ich sie festgelegt habe (192.168.10.1)
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Hat jetzt mein Code wirklich bei keinem Funktioniert?
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Wenn du eine schreibgeschützte Datei auf ein Netzlaufwerk packts, auf das alle clients Zugriff haben, müsste doch fileexists gehen, oder?
Ratte |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
also ich hab mal bei mir in die registry geschaut. da existieren die werte, die du da abfrgats nicht mal
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Hatte mich auch schon mit dem Thema rumgeärgert. Die Sachen mit Registry und MAC Adresse fallen raus, da das mit der Reg auf jedem Windows unterschiedlich ist und die MAC bei Entfernen des Kabels erhalten bleibt.
Habe aber gerade etwas gefunden bei delphi3000.com. bin mal so frei und liste den verwendeten Code:
Delphi-Quellcode:
Bei mir funktioniert das wunderbar, nach dem Rausziehen dauert es circa 5 sek, beim Reinstecken 1/2 sek bis es umschlägt.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, WinSock, ExtCtrls; type TForm1 = class(TForm) Button2: TButton; Timer1: TTimer; CheckBox1: TCheckBox; procedure Button2Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } function DetectHostIP: boolean; end; var Form1: TForm1; HostIP:String='Unknown'; implementation {$R *.dfm} function TForm1.DetectHostIP: Boolean; var wsdata: TWSAData; hostname: array[0..255] of char; hostEnt: PHostEnt; addr: PChar; begin WSAStartup($0101,wsdata); try gethostname(hostname,sizeof(hostname)); hostEnt := gethostbyname(hostname); if Assigned(hostEnt) then if Assigned(hostEnt^.h_addr_list) then begin addr := hostEnt^.h_addr_list^; if Assigned(addr) then begin HostIP := Format('%d.%d.%d.%d',[byte(addr[0]),byte(addr[1]),byte(addr[2]),byte(addr[3])]); Result := True; end else Result := False; end else Result := False else begin MessageDlg(Format('WinSock Error %d', [WSAGetLastError]),mtError,[mbOK],0); Result := False; end; finally WSACleanup; end; end; procedure TForm1.Button2Click(Sender: TObject); begin if DetectHostIP=True then ShowMessage(HostIP); end; procedure TForm1.Timer1Timer(Sender: TObject); begin if DetectHostIP=True then if HostIP <> '127.0.0.1' then CheckBox1.Checked := True //CheckBox sagt: Netzwerkkabel steckt else CheckBox1.Checked := False; //oder halt net end; end. Das Problem ist allerdings: Bei meinem Centrino 1.5 braucht das Prog 20% CPU. Das darf natürlich nicht sein. Habe aber grad keine Lust da ich morgen ne Algebra Klausur schreibe. Aber werde mich damit weiter befassen. Ciao Thomas |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Evtl. ist das hier was du suchst: RasConnectionNotification und evtl (wenn auch unwahrscheinlicher RasAdminConnectionHangupNotification
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Leider nein :?
Mir geht es ja um die lokale IP und keine Interneteinwahl. Aber nochmal zur Überlegung. Was soll angezeigt werden?
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Liste der Anhänge anzeigen (Anzahl: 1)
Hab's geschafft! Nach langem hin- und her hab ich die WMI zum laufen bekommen. Es werden jetzt alle Netzwerkadapter ausgegeben, die auch in "Netzwerkverbindungen" stehen, deren MAC-Adresse und Status (Connected/NOT Connected).
Probiert es mal bitte unter anderen OS als XP/SP1 aus und postet mal die Resultate.
Delphi-Quellcode:
Eingebunden wird das dann folgendermaßen:
unit UNetWMI;
interface uses // Delphi VCL Units Classes, Variants; // external forward declarations function getSystemMACAddresses: TStringList; implementation uses // Delphi VCL Units Windows, Dialogs, ComObj, ActiveX, // Imported type libraries WbemScripting_TLB; { Typelib name: "Microsoft Windows WMI Scripting V1.2 Library" } const // define used constants WMI_LOCAL_COMPUTER = '.'; WMI_SYSTEM_NAMESPACE = 'root\CIMV2'; WMI_CLASS_NIC = 'Win32_NetworkAdapter'; WMI_ATTRIB_ADAPTER = 'AdapterType'; WMI_ATTRIB_AVAILAB = 'NetConnectionID'; WMI_ATTRIB_CONNSTAT = 'NetConnectionStatus'; WMI_ATTRIB_MAC = 'MACAddress'; WMI_ATTRIB_NAME = 'Name'; // retrieve System MAC Addresses via WMI // function getSystemMACAddresses: TStringList; var l_WMILocator: ISWbemLocator; // Locator, gets Services l_WMIServices: ISWbemServices; // Services, gets Object Definitions l_WMIObjectDefinition: ISWbemObject; // Definition, gets Set of Objetcs l_WMIObjectSet: SWbemObjectSet; // ObjectSet, gets Enum over Instances l_WMIObjectInstances: IEnumVariant; // Enum of Instances, gets Object l_WMIObject: ISWbemObject; // Object, gets Sets of his properties l_WMIPropertySet: ISWbemPropertySet; // PropertySet, gets single property l_WMIProperty: ISWbemProperty; // Property, gets Value l_TempObj: OleVariant; // temporary used values l_ObjValue: Cardinal; begin // create the return object result := TStringList.Create; // retrieve object enum through WMI classes l_WMILocator := CoSWbemLocator.Create; l_WMIServices := L_WMILocator.ConnectServer(WMI_LOCAL_COMPUTER, WMI_SYSTEM_NAMESPACE, '', '', '', '', 0, nil); l_WMIObjectDefinition := l_WMIServices.Get(WMI_CLASS_NIC, wbemFlagUseAmendedQualifiers, nil); l_WMIObjectSet := l_WMIObjectDefinition.Instances_(0, nil); l_WMIObjectInstances := (l_WMIObjectSet._NewEnum) as IEnumVariant; // iterate through enum values (WbemObjects) and get the property values while (l_WMIObjectInstances.Next(1, l_TempObj, l_ObjValue) = S_OK) do begin l_WMIObject:= IUnknown(l_TempObj) as SWBemObject; l_WMIPropertySet := l_WMIObject.Properties_; l_WMIProperty := l_WMIPropertySet.Item(WMI_ATTRIB_AVAILAB, 0); if not VarIsNull(l_WMIProperty.Get_Value) then begin result.Add(l_WMIProperty.Get_Value); l_WMIProperty := l_WMIPropertySet.Item(WMI_ATTRIB_NAME, 0); if not VarIsNull(l_WMIProperty.Get_Value) then result.Append(' - '+l_WMIProperty.Get_Value); l_WMIProperty := l_WMIPropertySet.Item(WMI_ATTRIB_MAC, 0); if not VarIsNull(l_WMIProperty.Get_Value) then result.Append(' - '+l_WMIProperty.Get_Value) else result.Append(' - MAC-Address not available'); l_WMIProperty := l_WMIPropertySet.Item(WMI_ATTRIB_ADAPTER, 0); if not VarIsNull(l_WMIProperty.Get_Value) then result.Append(' - '+l_WMIProperty.Get_Value) else result.Append(' - Network Type not available'); l_WMIProperty := l_WMIPropertySet.Item(WMI_ATTRIB_CONNSTAT, 0); if l_WMIProperty.Get_Value=2 then result.Append(' - Status: Connected') else result.Append(' - Status: NOT Connected'); result.Add(''); end; end; end; end.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin ListBox1.Items := getSystemMACAddresses; end; Wer die WMI Library braucht, sollte hier vorbeischauen. Aber Achtung, waren circa 323MB zum downloaden. Anbei mal mein Versuchsprojekt :dp: |
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
also ich habs mal getestet ! bei mir unter WinXP home gehts einwandfrei allerdings unter WinME gehts gar nicht.
|
Re: Feststellen, ob Netzwerkkabel gezogen wurde?
Hmm, hab gerade gesehen dass es NetConnectionID erst ab XP gibt. Da ich kein Win98/ME mehr habe, wäre es schön wenn vielleicht jemand für diese Windows-Versionen was findet.
Die Funktionen von Win32_NetworkAdapter findet ihr hier [edit] @novabeat: kannst du mir bitte eine genaue Fehlerbeschreibung geben. An welcher Zeiler hängt es unter ME, etc? Danke |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:44 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