Программирование оконных сокетов в NSIS - PullRequest
1 голос
/ 13 января 2012

Я пытаюсь создать сокет в файле .nsi, чтобы проверить, будет ли сокет создан успешно или нет, чтобы проверить наличие порта. Поэтому любая помощь в отношении windows socket programmin в nsis высоко ценится.

спасибо

Ответы [ 2 ]

4 голосов
/ 14 января 2012
!include LogicLib.nsh

!ifndef AF_INET
!define AF_INET 2
!define SOCK_STREAM 1
!define IPPROTO_TCP 6
!define INADDR_ANY 0
!define SOL_SOCKET 0xffff
!define /math SO_EXCLUSIVEADDRUSE 0xffffffff ^ 0x4
!endif

Function QueryCanBindToIP4TCPPort
Exch $0
Push $1
Push $2
Push $0 ;Push port
System::Alloc 16 ;WSADATA & sockaddr_in
System::Call 'Ws2_32::WSAStartup(i 2,isr2)i.r0'
${If} $0 = 0
    System::Call 'Ws2_32::socket(i ${AF_INET},i ${SOCK_STREAM},i ${IPPROTO_TCP})i.r1 ?e'
    Pop $0
    ${If} $1 <> -1
        System::Call 'Ws2_32::setsockopt(ir1,i ${SOL_SOCKET},i ${SO_EXCLUSIVEADDRUSE},*i 1,i4)i.r0'
        System::Call 'Ws2_32::htons(iss)i.s' ;Convert port (and leaves the original push on the stack)
        ;Skipping htonl on address since INADDR_ANY is 0
        System::Call '*$2(&i2 ${AF_INET},&i2 s,&i4 ${INADDR_ANY},&i8 0)'
        System::Call 'Ws2_32::bind(ir1,ir2,i16)i.r0'
        ${If} $0 = 0
            System::Call 'Ws2_32::listen(ir1,i0)i.r0'
            ;Listening here but once we hit WSACleanup the port will be free again (This is fine if all you need to do is make sure no app is bound to the port at this moment)
            ; System::Call 'Ws2_32::closesocket(ir1)'
        ${EndIf}
    ${EndIf}
    System::Call 'Ws2_32::WSACleanup()' ;Remove this call to leave the port open for the duration of the installer
${EndIf}
System::Free $2
Pop $2 ;Throw away port
Pop $2
Pop $1
Exch $0
FunctionEnd

Section
Push 666
call QueryCanBindToIP4TCPPort
Pop $0
${If} $0 = 0
    DetailPrint "Bind OK"
${Else}
    DetailPrint "Bind Failed!"
${EndIf}
SectionEnd
0 голосов
/ 13 января 2012

Поскольку NSIS не имеет никаких сетевых функций, ни встроенных, ни в каких-либо плагинах, которые я смог найти, на мой взгляд, самое простое решение - создать очень маленькую программу, которая пытается создать сокет прослушивания на указанном португде порт может быть жестко задан или передан в качестве аргумента).Затем эту программу можно использовать в сценарии установки для проверки доступности порта.

...