Hola, lo que yo haría en tu caso si es que no fuese posible lograr lo que querés desde visual basic, usaría un lenguaje auxiliar, por lo que seguiría usando visual basic pero con la ayuda de otro lenguaje que si pueda hacer esa operación.
El método primero sería saber que lenguaje puede hacerlo, por ejemplo Python, C, C++, Powershell (aunque este último no sea un lenguaje pero puede tener posibles funciones) etc., luego crear el código que cumpla la función necesaria, entonces teniendo eso listo, podrías poner ese mismo código dentro de tu código vb y cuando haga falta ese código se copié por ejemplo en un directorio temporal de Windows creando un archivo para ejecutar las instrucciones y luego se borre o se borre cuando sea necesario.
En el caso de ser un programa ejecutable de por ejemplo un programa compilado como C++, se podría codificarlo en base64 y guardarlo dentro de tu código de vb, luego cuando se lo necesite usar, entonces se decodifica creando un archivo/programa ejecutable en algún directorio que puede ser en el mismo directorio dónde está tu script o en otro, por ejemplo en el directorio de archivos temporales de Windows.
Tal vez te preguntes si eso funcionaria y la respuesta es sí porque lo que un lenguaje no pueda hacer, lo hará otro que sí pueda, solamente tiene que llamar a ese otro código/programa, y el tema podríamos decir más complicado y el que más hay que tener en cuenta es el tema de la sincronización, los dos tienen que estar sincronizados y eso ya lo ves vos cómo hacerlo, podes hacerlo por ejemplo mediante archivos de texto o archivos de configuración ini, mientras uno escribe la información, el otro la lee, o hasta incluso usar sockets para la comunicación, yo en mis épocas he creado métodos como éstos y me han funcionado perfectamente.
Saludos
Se me ocurre con winapi listas los procesos, obtener el "comando" con el que fue ejecutado y todos los PID de ese ejecución pues será de ese perfil...
Una imagen dice mil palabras (el código de abajo esta enfocado en buscar esos comandos)
Pasos:
Listas procesos activos inspeccionando "PED".
Si vez que tienen los parámetros del perfil los matas
Este es un visor en C/C++
C/C++ ::
https://www.codeproject.com/Articles/19685/Get-Process-Info-with-NtQueryInformationProcessDebes listar los procesos (aquí un código que te puede servir
https://www.vbforums.com/showthread.php?251163-How-can-you-terminate-a-process-by-its-name&s=&highlight=terminateprocess) y obtener su handle después el handle lo puedes pasar a estos código que te dejo y que deberás adaptar según requieras.
Para inspeccionar las ejecuciones desde el handle podrías usar esto:
Option Explicit
Private Const ProcessBasicInformation As Long = 0
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
Public Type LIST_ENTRY64
Flink As LARGE_INTEGER
Blink As LARGE_INTEGER
End Type
Private Type UNICODE_STRING64
Length As Integer
MaxLength As Integer
lPad As Long
lpBuffer As LARGE_INTEGER
End Type
Private Type PROCESS_BASIC_INFORMATION64
ExitStatus As Long
Reserved0 As Long
PebBaseAddress As LARGE_INTEGER
AffinityMask As LARGE_INTEGER
BasePriority As Long
Reserved1 As Long
uUniqueProcessId As LARGE_INTEGER
uInheritedFromUniqueProcessId As LARGE_INTEGER
End Type
Public Type PEB64
InheritedAddressSpace As Byte
ReadImageFileExecOptions As Byte
BeingDebugged As Byte
Spare As Byte
lPad01 As Long
Mutant As LARGE_INTEGER
ImageBaseAddress As LARGE_INTEGER
LoaderData As LARGE_INTEGER
ProcessParameters As LARGE_INTEGER
SubSystemData As LARGE_INTEGER
ProcessHeap As LARGE_INTEGER
FastPebLock As LARGE_INTEGER
AtlThunkSListPtr As LARGE_INTEGER
IFEOKey As LARGE_INTEGER
CrossProcessFlags As Long
ProcessBits As Long
KernelCallBackTable As LARGE_INTEGER
EventLogSection As Long
EventLog As Long
FreeList As LARGE_INTEGER
TlsBitMapSize As Long
lPad02 As Long
TlsBitMap As LARGE_INTEGER
TlsBitMapData(1) As Long
ReadOnlySharedMemoryBase As LARGE_INTEGER
ReadOnlySharedMemoryHeap As LARGE_INTEGER
ReadOnlyStaticServerData As LARGE_INTEGER
InitAnsiCodePageData As LARGE_INTEGER
InitOemCodePageData As LARGE_INTEGER
InitUnicodeCaseTableData As LARGE_INTEGER
NumberOfProcessors As Long
NtGlobalFlag As Long
CriticalSectionTimeout As LARGE_INTEGER
HeapSegmentReserve As LARGE_INTEGER
HeapSegmentCommit As LARGE_INTEGER
HeapDeCommitTotalFreeThreshold As LARGE_INTEGER
HeapDeCommitFreeBlockThreshold As LARGE_INTEGER
NumberOfHeaps As Long
MaxNumberOfHeaps As Long
ProcessHeapsList As LARGE_INTEGER
GdiSharedHandleTable As LARGE_INTEGER
ProcessStarterHelper As LARGE_INTEGER
GdiDCAttributeList As Long
lPad03 As Long
LoaderLock As LARGE_INTEGER
NtMajorVersion As Long
NtMinorVersion As Long
NtBuildNumber As Integer
NtPlatformId As Integer
PlatformId As Long
ImageSubsystem As Long
ImageMajorSubsystemVersion As Long
ImageMinorSubsystemVersion As Long
lPad09 As Long
AffinityMask As LARGE_INTEGER
GdiHandleBuffer(29) As LARGE_INTEGER
PostProcessInitRoutine As LARGE_INTEGER
TlsExpansionBitmap As LARGE_INTEGER
TlsExpansionBitmapBits(31) As Long
SessionId As LARGE_INTEGER
AppCompatFlags As LARGE_INTEGER
AppCompatFlagsUser As LARGE_INTEGER
ShimData As LARGE_INTEGER
AppCompatInfo As LARGE_INTEGER
CSDVersion As UNICODE_STRING64
ActivationContextData As LARGE_INTEGER
ProcessAssemblyStorageMap As LARGE_INTEGER
SystemDefaultActivationData As LARGE_INTEGER
SystemAssemblyStorageMap As LARGE_INTEGER
MinimumStackCommit As Long
lPad05 As Long
FlsCallBack As LARGE_INTEGER
FlsListHead As LIST_ENTRY64
FlsBitmap As LARGE_INTEGER
FlsBitmapBits(3) As Long
FlsHighIndex As Long
lPad06 As Long
WerRegistrationData As LARGE_INTEGER
WerShipAssertPtr As LARGE_INTEGER
End Type
Private Declare Function NtWow64QueryInformationProcess64 Lib "ntdll" ( _
ByVal hProcess As Long, _
ByVal ProcessInformationClass As Long, _
ByRef pProcessInformation As Any, _
ByVal uProcessInformationLength As Long, _
ByRef puReturnLength As Long) As Long
Private Declare Function NtWow64ReadVirtualMemory64 Lib "ntdll" ( _
ByVal hProcess As Long, _
ByVal BaseAddressL As Long, _
ByVal BaseAddressH As Long, _
ByRef Buffer As Any, _
ByVal BufferLengthL As Long, _
ByVal BufferLengthH As Long, _
ByRef ReturnLength As LARGE_INTEGER) As Long
Sub Main()
Dim tPBI As PROCESS_BASIC_INFORMATION64
Dim tPeb As PEB64
Dim lStatus As Long
Dim hProcess As Long
Dim liRet As LARGE_INTEGER
' // Your handle
hProcess = -1
lStatus = NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, tPBI, Len(tPBI), 0)
If lStatus < 0 Then
MsgBox "Error 0x" & Hex$(lStatus)
Exit Sub
End If
lStatus = NtWow64ReadVirtualMemory64(hProcess, tPBI.PebBaseAddress.lowpart, tPBI.PebBaseAddress.highpart, tPeb, Len(tPeb), 0, liRet)
If lStatus < 0 Then
MsgBox "Error 0x" & Hex$(lStatus)
Exit Sub
End If
End Sub
Este código los mata por nombre (busca por nombre los ejecutables obtiene su pid y los mata, en tu caso debes remover el codigo que busca por nombre y solo pasar el PID).
Public Function KillAppByName(MyName As String) As Boolean 'kills applications by name
Const PROCESS_ALL_ACCESS = 0
Dim uProcess As PROCESSENTRY32
Dim rProcessFound As Long
Dim hSnapshot As Long
Dim szExename As String
Dim exitCode As Long
Dim AppKill As Long
Dim i As Integer
Dim lProcHnd As Long
Dim hWnd As Long
On Local Error GoTo ErrTrap
If winVersion = "WNT3" Or winVersion = "WNT4" Then Exit Function
Const TH32CS_SNAPPROCESS As Long = 2&
uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
i = InStr(1, uProcess.szexeFile, Chr(0))
szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
If Right$(szExename, Len(MyName)) = LCase$(MyName) Then
lProcHnd = OpenProcess(PROCESS_TERMINATE, 0&, uProcess.th32ProcessID)
AppKill = TerminateProcess(lProcHnd, exitCode)
Call CloseHandle(lProcHnd)
End If
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
Call CloseHandle(hSnapshot)
Exit Function
End Function
Dulces lunas!¡.