Страница 1 из 2

Подключение/отключение по локальной сети

Добавлено: Чт фев 11, 2010 01:56
Flasher
Задача: иметь на панели рабочую кнопку активации/деактивации "Подключения по локальной сети" с учётом статического IP. При активации подключения по нажатию должно выводиться диалоговое окно состояния. Естественно никакие rasdial-ы тут не пройдут. Ну допустим подключение можно осуществить путём создание "Подключение по локальной сети.lnk" на Раб. столе и подвешивания на панель Тотала, и то почему-то это не всегда работает или вообще не работает, пусть и при включённых стрелках на lnk. Конечно можно было бы задействовать "devcon disable PCI\VEN_....", где скрипт искал бы в коде экземпляра сетевого PCI-устройства первые 4 символа идентификатора ID после: "\VEN_" и присваивал в нужном месте команды. Но тогда как быть с диал. окном состояния? Видится здесь батником не обойтись. Но это всё догадки. Дело остаётся за главным, за экспертами. 8)
Буду благодарен за любые достойные решения! :)

Добавлено: Чт фев 11, 2010 09:10
D1P
Требуется именно отключение сетевухи, или достаточно логического (чтобы через интерфейс сетевухи не проходили IP-пакеты)?

Добавлено: Чт фев 11, 2010 11:12
Flasher
D1P, ну через devcon это я как один из вариантов предложил. Если можно, скажем, через netsh, то было бы ничуть не хуже. Логический метод тоже устроит. Но и включаться должно также просто по кнопке. И не забыть бы про вывод диалогового окна, не знаю насколько вообще его реально вызвать через rundll32 или ещё как-то.

Добавлено: Чт фев 11, 2010 11:25
D1P
Перечитал исходный пост, понял, что тебе не отключение нужно, а ещё и подключение, да и с окном состояния не помогу.

Добавлено: Чт фев 11, 2010 11:30
Flasher
даа, посты надо читать, а ещё лучше начать с названия темы. :wink:

Добавлено: Чт фев 11, 2010 12:01
D1P
Flasher писал(а):даа, посты надо читать, а ещё лучше начать с названия темы.
Я посчитал, что у тебя есть постоянное сетевое соединение, которое, время от времени нужно выключать и включать. Но у тебя что-то другое, чей логики я не понимаю.

Добавлено: Чт фев 11, 2010 12:10
Flasher
Да у меня статический IP(постоянное соед.), не через шлюз, я же писал. Почему другое?

Добавлено: Чт фев 11, 2010 13:07
D1P
Flasher писал(а):Да у меня статический IP(постоянное соед.)
Ну тогда выключай маршрутизацию по интерфейсу, а когда сеть необходимо восстановить - включай. Команда route.

Добавлено: Чт фев 11, 2010 14:01
Flasher
D1P писал(а):Ну тогда выключай маршрутизацию по интерфейсу, а когда сеть необходимо восстановить - включай. Команда route.
Вот так?:
route add(delete) xxx.xx.xxx.x mask 255.255.xxx.xxx xxx.xx.xxx.x if 0x2
В любом случае добавление и удаление маршрута моей задачи не решает. К тому же надо автоматизировать, чтобы одной кнопкой было, которая должна работать с любого компа, где есть статика, чтобы ручками ничего не править. Ну а с получением состояния с динамической сменой пакетов надо что-то делать(на сколько я понимаю в CMD это не реально((netstat -e; -s), да и чёрное окно ни к чему, нужно нормальное диал. окно, но с этим уже, как я понял, не к D1P.

Добавлено: Пт мар 05, 2010 11:15
Flasher
Пару недель назад нашёл несколько раздельных решений своего вопроса. Решил таки выложить. Надеюсь кому-то будет полезным. Хотелось бы увидеть мнение о работоспособности предложенного людей с динамическим IP, а также у кого не WinXP, а, скажем, семёрка или Виста.

Ну первый и известный многим способ, упомянутый в первом посте, это включение/выключение сетевой платы с помощью devcon . Код кнопки:
  • TOTALCMD#BAR#DATA
    devcon
    enable(disable) PCI\VEN_xxxx
    Путь\ваша библиотека иконок.dll,№
    Включить(Отключить) сетевую карту (сеть, интернет)
    %COMMANDER_PATH%\Utils\

    -1
Положите devcon.exe, например, в папку Utils вашего Коммандера. Откройте Диспетчер устройств(Device Manager), в секции <Сетевые платы> вызовите Свойства своей из контекстного меню, перейдите на вкладку <Сведения>, из окошка скопируйте четыре символа после PCI\VEN_ и вставьте в графу Параметры этой кнопки вместо xxxx

Следующий способ с помошью батника:

Код: Выделить всё

@echo off
if {%3}=={} @echo Syntax: ConnInterface Action InterfaceName Status&goto :EOF
setlocal
set Action=%1
set IFN=%2
set Action=%Action:"=%
if /i "%action%" EQU "C" goto con
if /i "%action%" EQU "D" goto dis
if /i "%action%" EQU "S" goto sta
@echo Error: ConnInterface %1 %2 %3 - Action is must be C,D, or S
endlocal
goto :EOF
:con
set IC=cnic %IFN% -c -s -v
goto doit
:dis
set IC=cnic %IFN% -d -s -v
goto doit
:sta
set status=E
set wrk=E
for /f "Tokens=*" %%s in ('cnic %IFN% -s -v^|find "connected"') do (
 set wrk=%%s
)
set wrk=%wrk:"=%
if "%wrk%" EQU "E" goto finish
set wrk=%wrk:*disconnected=D%
if "%wrk%" EQU "D" set status=D&goto finish
set wrk=%wrk:*connected=C%
if "%wrk%" EQU "C" set status=C
:finish
endlocal&set %3=%status%
goto :EOF
:doit
set status=E
for /f "Tokens=*" %%s in ('%IC%^|find "Operation succeded"') do (
 set status=Y
)
if "%status%" EQU "E" goto finish
goto sta
Сохраните код, например, в ConnInterface.bat , положите его в каталог вместе с распакованным отсюда CNic.exe
Код кнопки для него:
  • TOTALCMD#BAR#DATA
    %COMMANDER_PATH%\Utils\chp\chp.exe ConnInterface
    C(D) "Подключение по локальной сети" %PATHEXT%
    Icons\Включить(Выключить)_сеть.ico
    Включить(Выключить) локальную сеть (интернет)
    %COMMANDER_PATH%\Utils\ConnInterface\
    1
    -1
Утилита chp скрывает чёрные окна.

Ну и третий способ выкладываю для пишущих в Autoit, поскольку требуется в доработке. В отличии от предыдущих должен удовлетворять моей задаче Включать/Выключать одной кнопкой. Ведёт себя некорректно, постоянно идёт на включение(к автору пока не обращался).

Код: Выделить всё

 _NetConnection_Verb("Подключение по локальной сети", "&Отключить")

MsgBox (48, "Сообщение", "Адаптер отключен!")

 _NetConnection_Verb("Подключение по локальной сети", "&Включить")

MsgBox (64, "Сообщение", "Адаптер включен!")

Func _NetConnection_Verb($sConnectionName, $sVerb)
    Local $sFolderName = "Сетевые подключения"
    Local $oNetConnections, $oConnection
    Local $oShellApp = ObjCreate("Shell.Application")
    Local $oControlPanel = $oShellApp.Namespace(3)
    For $oFolderItem In $oControlPanel.Items
        If $oFolderItem.Name = $sFolderName Then
            $oNetConnections = $oFolderItem.GetFolder
            ExitLoop
        EndIf
    Next
    If Not(IsObj($oNetConnections)) Then Return SetError(1, 0, False)
    For $oFolderitem In $oNetConnections.Items
        If StringInStr($oFolderitem.Name, $sConnectionName) Then
            $oConnection = $oFolderitem
            ExitLoop
        EndIf
    Next
    If Not(IsObj($oConnection)) Then Return SetError(2, 0, False)
    $oConnection.InvokeVerb($sVerb)
    Sleep(1000)
EndFunc
Если возникнет реализация объединения в одну кнопку Connect/Disconnect по одному из из первых двух способов, буду примного благодарен.

Добавлено: Пт мар 05, 2010 11:38
Flasher
Ещё конечно же меня волновала реализация запуска окна Состояние Подключение по локальной сети(Local Area Connection Status). Пока реализовать не удалось. Не знаю, может можно попробывать через Visual Basic с подобным синтаксисом(я в этом не силён):
  • ShellExecute(0, 0, "file:///::{BA126ADB-2166-11D1-B1D0-00805FC1270E}", 0, 0, SW_SHOWNORMAL);
  • ShellExecute(0, "open", "file:///::{BA126ADB-2166-11D1-B1D0-00805FC1270E}", 0, 0, SW_SHOWNORMAL);
    dsds
Пока найдена только альтернатива в виде Autohotkey для показа хода пакетов(что собственно мне и нужно). Но опять же не лишена недостатков(лезет в инет, аккумулируется с каким-то сервером для подсчёта статистики, числа на Upload не соотв. протоколу в окне Cостояние... Опять же для интузиастов но уже ahk-скриптинга:

Код: Выделить всё

#SingleInstance, Force 
DetectHiddenWindows, OFF             ; OFF is default, but this script would err if set ON 

Menu, Tray, NoStandard 
Menu, Tray, Add, Show/Hide, ShowHide 
Menu, Tray, Add 
Menu, Tray, Standard 
Menu, Tray, Default, Show/Hide 
Menu, Tray, Icon, NetShell.dll, 58 

IfNotExist, %A_Temp%\NetStatus.bmp 
UrlDownloadToFile, http://www.autohotkey.net/~goyyah/samples/grad001.bmp 
, %A_Temp%\NetStatus.bmp 

Gui -Caption +Border +ToolWindow +AlwaysOnTop +LastFound 
GuiID := WinExist() , prv_iNo := 44 
Gui, Color , FFFFEE 
Gui, Margin, 0, 0 
Gui, Font  , s8, Verdana 
Gui, Add, Picture, x40   y0   w200 h40 vConn  GuiMove, %A_Temp%\NetStatus.bmp 
Gui, Add, Picture, x5    y6     Icon30 vIcon  GuiMove, NetShell.dll 
Gui, Add, Text   , x+7   y3    w75  h16 +Border 
Gui, Add, Text   , xp+1  yp+1  w70  h14 +0x200 c5B0000 +Right  HWNDSent 
Gui, Add, Text   , xp-1  y+3   w75  h16 +Border 
Gui, Add, Text   , xp+1  yp+1  w70  h14 +0x200 c5B0000 +Right  HWNDRecv 
Gui, Add, Text   , x+7   y3    w80  h16 +Border    
Gui, Add, Text   , xp+4  yp+1  w75  h14 c003D00                HWNDkbps  
Gui, Font, Bold 
Gui, Add, Text   , xp-4  y+3   w80  h16 +Border 
Gui, Add, Text   , xp+4  yp+1  w75  h14 c003D00                HWNDband  

IniRead, X, %A_Temp%\%A_ScriptName%.INI, GuiPos, XPos, 20 
IniRead, Y, %A_Temp%\%A_ScriptName%.INI, GuiPos, YPos, 20 

Gui, Show, x%x% y%y% w205 h40, NetMeter 

If GetIfTable(tb) 
   ExitApp 

Loop, % DecodeInteger(&tb) { 
   If DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 544) < 4 
   || DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 516) = 24 
      Continue 

   ptr := &tb + 4 + 860 * (A_Index - 1) 
      Break 
                           } 
IfLess, ptr, 1, ExitApp 
SetTimer, NetMeter 

Return ; ------------------------------------------------------- AutoExecute Section ends 

NetMeter: 
   SetTimer, NetMeter, Off 
   DllCall("iphlpapi\GetIfEntry", "Uint", ptr) 

   dnNew := DecodeInteger(ptr + 552)   ,    upNew  := DecodeInteger(ptr + 576)      
   dnRate := Round((dnNew - dnOld) )   ,    upRate := Round((upNew - upOld) ) 
   PollMs := (dnRate - upRate = 0) ? 1024 : 256 

   Menu, Tray, Tip, % "Sent: " upNew " / Recv: " dnNew " / Total: " 
                  . Round((((upNew+dnNew) /1024)/1024),1) . " MB" 

   ; Determine & update GUI-Icon & Tray-Icon 
   IfGreater,dnRate,0,  IfGreater,upRate,0,  SetEnv,iNo,41     ;  Recv/Sent 
   IfGreater,dnRate,0,  IfEqual  ,upRate,0,  SetEnv,iNo,42     ;  Recv 
   IfEqual  ,dnRate,0,  IfGreater,upRate,0,  SetEnv,iNo,43     ;  Sent 
   IfEqual  ,dnRate,0,  IfEqual  ,upRate,0,  SetEnv,iNo,44     ;  None 
   IfNotEqual,iNo, %prv_iNo%,  Menu, Tray, Icon, NetShell.dll, % iNo+14 

   If WinExist( "ahk_id " . GuiID )  {                ; Update the GUI Data 
   ControlSetText,, %upNew%                                         , ahk_id %Sent%    
   ControlSetText,, %dnNew%                                         , ahk_id %Recv% 
   ControlSetText,, % Round((dnrate+uprate)/PollMs) . " KBps"       , ahk_id %Kbps% 
   ControlSetText,, % Round((((upNew+dnNew) /1024)/1024),1) . " MB" , ahk_id %Band% 
   IfNotEqual,iNo, %prv_iNo%,  GuiControl,, Icon, *Icon%iNo% NetShell.dll 
                                     } 

   prv_iNo := iNo , dnOld := dnNew , upOld := upNew 
   SetTimer, NetMeter, %PollMs% 
Return 

uiMove: 
   PostMessage, 0xA1, 2,,, A 
   Sleep 200 
   WinGetPos, X, Y 
   IniWrite, %X%, %A_Temp%\%A_ScriptName%.INI, GuiPos, XPos 
   IniWrite, %Y%, %A_Temp%\%A_ScriptName%.INI, GuiPos, YPos 
Return 

ShowHide: 
   GuiControl,, Icon, *Icon%iNo% NetShell.dll 
   IfWinExist, ahk_id %GuiID%,,,, WinHide, ahk_id %GuiID% 
   Else                           WinShow, ahk_id %GuiID% 
Return 

GuiContextMenu: 
   Menu, Tray, Show 
Return 

GetIfTable(ByRef tb, bOrder = False) { 
   nSize := 4 + 860 * GetNumberOfInterfaces() + 8 
   VarSetCapacity(tb, nSize) 
   Return DllCall("iphlpapi\GetIfTable", "Uint", &tb, "UintP", nSize, "int", bOrder) 
                                     } 

GetIfEntry(ByRef tb, idx)            { 
   VarSetCapacity(tb, 860) 
   DllCall("ntdll\RtlFillMemoryUlong", "Uint", &tb + 512, "Uint", 4, "Uint", idx) 
   Return DllCall("iphlpapi\GetIfEntry", "Uint", &tb) 
                                     } 

GetNumberOfInterfaces()              { 
   DllCall("iphlpapi\GetNumberOfInterfaces", "UintP", nIf) 
   Return nIf 
                                     } 

DecodeInteger(ptr)                   { 
   Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24 
                                     }

Добавлено: Пт окт 12, 2012 18:23
name8
для показа хода пакетов
нет, не пакетов, а принятых и отправленных байт.
лезет в инет
да, за фоновым рисунком "NetStatus.bmp" -
просто закомментируйте строки с "NetStatus.bmp".
аккумулируется с каким-то сервером для подсчёта статистики
это выдумки.
числа на Upload не соотв. протоколу в окне Cостояние...
для отображения количества пакетов, а не байт, нужны другие значения (dwInUcastPkts и dwOutUcastPkts) вместо 552 (dwInOctets) и 576 (dwOutOctets) в строке:
dnNew := DecodeInteger(ptr + 552) , upNew := DecodeInteger(ptr + 576)

А зная значение dwOperStatus можно отображать и состояние подключения. Есть и другие полезные параметры.

Добавлено: Пт окт 12, 2012 22:38
Flasher
Никакой новой информации для меня тут нет. Правка постов у нас живёт не более месяца. Не советую приходить на форум с собранной критической массой, иначе она обратиться против вас, тем более что тема устарела (ей 2.5 года) и почти кроме меня никем не поддерживалась. Для себя уже давно написал vbs-скрипт, полностью меня удовлетворяющий. И писал я не об отображении пакетов/байт, а о соответствии.

Добавлено: Сб окт 13, 2012 17:35
name8
Да не "потоков", а пакетов.
в окне Cостояние... отображаются ПАКЕТЫ.
А в приведённом скрипте - байты.
Какое уж тут соответствие.

Чтобы не путать тех, кто сюда заходит,
исправляйте свои посты, или удаляйте совсем.

Добавлено: Сб окт 13, 2012 19:10
Flasher
Насчёт пакетов просто описался. Потоки пакетов/байт, если угодно, не соответствуют друг другу. Такое уж несоответствие.

Никто или почти никто сюда заходить не будет, а уж тем более обращать внимание на такие мелочи, если такие как вы не будете поднимать старые никем не поддержанные темы.
Удалять старые сообщения нельзя ровно так же, как и редактировать, так что совет опять неуместен.

Хотите позаниматься отловом несостоятельности или неправомерности чьих то слов? Тогда от ваc куда больше будет пользы как от редактора статей на TCKB, если вы в тематике ТС как следует смыслите. А пока ваша деятельность тут имеет сверхнизкий КПД.