[C++] Need to kill a process listening on a specific port

Discussion in 'Mixed Languages' started by CODYQX4, Nov 1, 2012.

  1. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,228
    150
    It seems that my KMSEmulator sometimes won't run as the port gets used up, most likely by "KMS Connection Broker".

    I want to in C++ have a way to kill any processes listening on port 1688 so I can run.

    I don't want to use netstat or batch in C++ code.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,456
    66,481
    300
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,228
    150
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  4. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,456
    66,481
    300
    #4 Daz, Nov 3, 2012
    Last edited by a moderator: Apr 20, 2017
    Code:
    FOR /F "tokens=5 delims= " %%P IN ('netstat -ano ^| findstr :1688') DO taskkill.exe /f /PID %%P
    XP should be tokens=4
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,228
    150
    #5 CODYQX4, Nov 3, 2012
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Problem is XP Home doesn't have taskkill.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  6. Tito

    Tito Super Mod / Adviser
    Staff Member

    Nov 30, 2009
    17,579
    15,397
    340
    #6 Tito, Nov 3, 2012
    Last edited by a moderator: Apr 20, 2017
    Implement timesurfer's logic ;)

    Code:
    if not exist "%Windir%\system32\schtasks.exe" ( cls
    echo You don't have schtasks.exe installed
    echo.
    echo IORRT is not compatable with XP Home Edition
    echo Install XP Professional or schtasks.exe
    ping -n 10 127.0.0.1 >NUL
    goto MAINMENU
    )
    
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,456
    66,481
    300
    #7 Daz, Nov 3, 2012
    Last edited by a moderator: Apr 20, 2017
    It should have tskill though :g:
    Code:
    FOR /F "tokens=4 delims= " %%P IN ('netstat -ano ^| findstr :1688') DO tskill.exe %%P /a
    You could also return the result and use WinAPI to do the kill:
    Code:
    BOOL TerminateProcess(DWORD dwProcessId, UINT uExitCode)
    {
        DWORD dwDesiredAccess = PROCESS_TERMINATE;
        BOOL  bInheritHandle  = FALSE;
        HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
        if (hProcess == NULL)
            return FALSE;
    
        BOOL result = TerminateProcess(hProcess, uExitCode);
        CloseHandle(hProcess);
        return result;
    }
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  8. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,228
    150
    #8 CODYQX4, Nov 3, 2012
    Last edited by a moderator: Apr 20, 2017
    (OP)
    I thought of using WinAPI to kill it, but how would you get the Process ID from batch into a C++ integer variable?
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. Pr3acher

    Pr3acher MDL Member

    Aug 24, 2012
    142
    48
    10
    I'm not sure i understand what you mean: you want to retrieve PID from a batch and kill process with C++ , is that right ?
    if it is, a solution could exists but not clean ^^: you can retrieve PID with batch and write it in txt file, open it in C++ read it in a buffer and kill process, the remove txt file...

    otherwise, have a look at GetProcessId function -> http://msdn.microsoft.com/fr-fr/library/windows/desktop/ms683215(v=vs.85).aspx
     
  10. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,456
    66,481
    300
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  11. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,228
    150
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  12. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,456
    66,481
    300
    #12 Daz, Nov 4, 2012
    Last edited by a moderator: Apr 20, 2017
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  13. Pr3acher

    Pr3acher MDL Member

    Aug 24, 2012
    142
    48
    10
    Well, i've done exactly what you mean in a project. You can redirect I/O using pipe, but there's also the _popen() function, use it like this:

    FILE *pRc=NULL;

    pRc=_popen("cscript.exe %windir%\\system32\\slmgr.vbs -dlv | FINDSTR /i \"count\"","r");//As system but auto-redirect output in a pipe
    fgets(rCBuff,sizeof(rCBuff),pRc);//Output will be stored in rcBuff

    it's the simplest way i found to redirectI/O in C
    Hope it helps..
     
  14. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,456
    66,481
    300
    Same as the example in the link as it uses popen, fgets and pclose :p
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  15. Pr3acher

    Pr3acher MDL Member

    Aug 24, 2012
    142
    48
    10
    Oh sry i've just seen your link ^^
     
  16. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,228
    150
    #16 CODYQX4, Nov 4, 2012
    Last edited by a moderator: Apr 20, 2017
    (OP)
    OK this is the code so far

    Code:
    // Get OS Version
    OSVERSIONINFO osvi;
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    ::GetVersionEx( &osvi );
    
    // Netstat tokens based on OS Version
    char *tstCommand;
    if (osvi.dwMajorVersion == 5)
    {
    tstCommand = "FOR /F \"tokens=5 delims= \" %P IN ('netstat -ano ^| findstr :1688') DO echo %P";
    printf("OS is Version 5\n");
    }
    else if (osvi.dwMajorVersion >= 6)
    {
    tstCommand = "FOR /F \"tokens=5 delims= \" %P IN ('netstat -ano ^| findstr :1688') DO echo %P";
    printf("OS is Version 6+\n");
    }
    
    // Kill Process that is using the port
    FILE *fp ;
    char path[MAX_PATH];
    fp = _popen(tstCommand, "r");
    while (fgets(path, MAX_PATH, fp) != NULL)
    {
    printf(path);
    }
    
    _pclose(fp);
    I simply print it. For some reason it echoes twice (same if I run the command from cmd). Because the record is returned twice.

    I simply print here. I need to parse out the PID. How could I store the output so I could Regex it into an int?
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  17. master131

    master131 MDL Novice

    Apr 12, 2011
    45
    22
    0
    #17 master131, Nov 5, 2012
    Last edited by a moderator: Apr 20, 2017
    You should probably avoid using Regex, especially in C++. You can approach it using the std::string class.

    Code:
    FILE *fp;
    char path[MAX_PATH];
    fp = _popen("netstat -anno | findstr :1688", "r");
    while (fgets(path, MAX_PATH, fp) != NULL)
    {
    std::string sProcessId(path);
    // Trim any whitespaces at the end of the string.
    sProcessId.erase(sProcessId.find_last_not_of(' ') + 1);
    // Only take the part of the string after the last space.
    sProcessId = sProcessId.substr(sProcessId.find_last_of(' ') + 1);
    // Convert the process Id string to an integer.
    int iProcessId = atoi(sProcessId.c_str());
    }
    _pclose(fp);
     
  18. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,228
    150
    OK that helps and it is working now.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...