General information
Category:
Internet applications
>Hi:
>
>How do you stop a COM server so you can recompile? I read I could use KILL INETINFO and KILL -f INETINFO from the command line, but neither works. I get error messages. It is a total pain in the ass to have to restart your machine each time you want to recompile! I'm using NT4.0.
>
>Thanx,
>Charlie
Here is some down and dirty code I use to kill a DLL COM server when it dosen't release properly and I want to re-compile. I hard coded the process name, 'VFP', and the DLL name because I was too lazy to make a robust utility, but it seems to work. Good luck.
Gary Foster
#DEFINE PROCESS_TERMINATE (0x0001)
#DEFINE PROCESS_CREATE_THREAD (0x0002)
#DEFINE PROCESS_VM_OPERATION (0x0008)
#DEFINE PROCESS_VM_READ (0x0010)
#DEFINE PROCESS_VM_WRITE (0x0020)
#DEFINE PROCESS_DUP_HANDLE (0x0040)
#DEFINE PROCESS_CREATE_PROCESS (0x0080)
#DEFINE PROCESS_SET_QUOTA (0x0100)
#DEFINE PROCESS_SET_INFORMATION (0x0200)
#DEFINE PROCESS_QUERY_INFORMATION (0x0400)
#DEFINE PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \0xFFF)
#DEFINE LOC_STRLEN 300
LOCAL nGot && Number of processes returned
LOCAL cProcesses && Array of DWORDS
LOCAL hModule && DWORD module handle
LOCAL cBuff && Maybe not needed
LOCAL nPtr && Pointer used for converting DWORDS to integers
LOCAL nNumOfProcesses
LOCAL nInc
LOCAL nSizeOfFilename
LOCAL nBoolval
LOCAL lRetVal
LOCAL cName
LOCAL nHandleFlag
LOCAL nSizeOfArray && One DWORD, four bytes
lRetVal = .F.
nBoolval = 0
nInc = 0
nBytesReturned = 0
nSizeOfArray = 4
hModule = CHR(0)+CHR(0)+CHR(0)+CHR(0)
cName = REPLICATE(CHR(0),40)
nHandleFlag = 0
hProcess = 0
nGot = 0
cProcesses = CHR(96)+CHR(0)+CHR(0)+CHR(0)+REPLICATE(CHR(0),92)
nPtr = 1
declare integer FreeLibrary in win32api integer
declare integer GetModuleHandle in win32api string @
DECLARE INTEGER EnumProcesses IN PSAPI STRING @cProcesses, INTEGER, INTEGER @nGot
DECLARE INTEGER OpenProcess IN WIN32API INTEGER nAccess, INTEGER nHandleFlag, INTEGER hProcess
DECLARE INTEGER EnumProcessModules IN PSAPI INTEGER hProcess, STRING @hModule, INTEGER nSizeOfArray, INTEGER @nBytesReturned
DECLARE INTEGER GetModuleFileNameEx IN PSAPI INTEGER hProcess, INTEGER hModule, STRING @cName, INTEGER, nSize
DECLARE INTEGER GetModuleBaseName IN PSAPI INTEGER hProcess, INTEGER hModule, STRING @cName, INTEGER nSize
*-- EnumProcesses is passed a pointer to an array of DWORDs, i.e., four byte strings and a pointer to
*-- an INTEGER that will hold the number of DWORDs filled with process ID's. It's impossible
*-- to know in advance the number of processes so 24 is a guess. 24*4 = the 96 chr(0) length)
nBoolval = EnumProcesses(@cProcesses,96,@nGot)
*-- Dimension an array of the proper size based on the processes returned value, nGot
nNumOfProcesses = nGot/4
DIMENSION aProcesses[nNumOfProcesses,2]
*-- Load the array with integer values derived from the DWORDs
FOR nInc = 1 TO nNumOfProcesses
* cBuff = substr(cProcesses,nPtr,4)
aProcesses[nInc,1] = CharToBin(SUBSTR(cProcesses,nPtr,4))
nPtr = nPtr + 4
ENDFOR
*-- Run through the process IDs and determine the process file name.
FOR nInc = 1 TO nNumOfProcesses
*-- Set/re-set the variables used for each iteration.
hModuleList = REPLICATE(CHR(0), LOC_STRLEN)
cName = REPLICATE(CHR(0),80)
nSizeOfFilename = 0
nBoolval = 0
*-- The SystemIdleProcess has a 0 for the PID, ignore it.
IF aProcesses[nInc,1] > 0
*-- OpenProcess returns a process handle for a specified process ID.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ,0,aProcesses[nInc,1])
*-- Non-zero return value indicates success.
IF hProcess > 0
*-- EnumProcessModules takes the process handle and loads the module array (an array of DWORDs) with module handles.
*-- We are only interested in the main module here so we only pass a pointer to a single four byte string.
nBoolval = EnumProcessModules(hProcess,@hModuleList,LOC_STRLEN,@nBytesReturned)
*-- Non-zero return value indicates success.
IF nBoolval > 0
nNumOfModules = nBytesReturned/4
*-- Load the array with integer values derived from the DWORDs
nPtr = 1
cName = REPLICATE(CHR(0),80)
nSizeOfFilename = 0
nBoolval = 0
hModule = CharToBin(SUBSTR(hModuleList,1,4))
nSizeOfFilename = GetModuleFileNameEx(hProcess, hModule, @cName, 80)
IF nSizeOfFilename > 0 AND "VFP"$cName
FOR nInc2 = 1 TO nNumOfModules
cName = REPLICATE(CHR(0),80)
nSizeOfFilename = 0
nBoolval = 0
hModule = CharToBin(SUBSTR(hModuleList,nPtr,4))
*-- Gets the filename with complete path.
nSizeOfFilename = GetModuleFileNameEx(hProcess, hModule, @cName, 80)
*-- Gets the filename without path.
* nSizeOfFilename = GetModuleBaseName(hProcess, hModule, @cName, 80)
nPtr = nPtr + 4
IF nSizeOfFilename > 0
IF nInc2 = 1
* ? LEFT(cName,nSizeOfFilename)
ELSE
cSoonToDie = LEFT(cName,nSizeOfFilename)
IF "starbase.dll"$lower(cSoonToDie)
IF FreeLibrary(hModule) > 0
MessageBox("Starbase is kaput!")
else
MessageBox("Starbase is Nosferatau!")
endif
ENDIF
ENDIF
ENDIF
ENDFOR
ENDIF
ENDIF
ENDIF
ENDIF
ENDFOR
RETURN lRetVal
FUNCTION CharToBin(tcBuff)
*-- This assumes passed string is four bytes or less.
nReturn = IIF(LEN(tcBuff)>0,ASC(SUBSTR(tcBuff, 1,1)), 0) + ;
IIF(LEN(tcBuff)>1,ASC(SUBSTR(tcBuff, 2,1)) * 256, 0) + ;
IIF(LEN(tcBuff)>2,ASC(SUBSTR(tcBuff, 3,1)) * 65536, 0) + ;
IIF(LEN(tcBuff)>3,ASC(SUBSTR(tcBuff, 4,1)) * 16777216, 0)
RETURN (nReturn)
ENDFUNC
FUNCTION BinToChar(tnValue)
LOCAL cBuff, byte1, byte2, byte3, byte4
cBuff = ""
IF tnValue > 16777215
cBuff = CHR(255)+CHR(255)+CHR(255)+CHR(255)
ELSE
byte4 = INT(tnValue/(256^3))
byte3 = INT(MOD(tnValue,(256^3))/ (256^2))
byte2 = INT(MOD(MOD(tnValue,(256^3)),(256^2))/256)
byte1 = INT(MOD(MOD(MOD(tnValue,(256^3)),(256^2)),256))
*-- Now stuff the a temporary string with the new value
cBuff = CHR(byte1) + CHR(byte2) + CHR(byte3) + CHR(byte4)
ENDIF
RETURN cBuff
ENDFUNC
Previous
Next
Reply
View the map of this thread
View the map of this thread starting from this message only
View all messages of this thread
View all messages of this thread starting from this message only