> How can you detect applications that are running on a network?
I do not rember where I got this function but it will tell you what users have a file open. This can be any file, including a .exe. However, you must pass the following info about the file. For instance if the file you are looking for is \\MyServerName\Programs\MyProgram.Exe...
tcServerName - The computer name of the server where the file resides e.g. MyServerName
tcBasePath - The path of the file on the server - C:\Programs\MyProgram.Exe
tcUserName - The name of the user to look for. Pass "" for all users
tcFileUsers - The address of an array to store the results e.g. @MyArray
&& FileUsers returns users of a file
parameters tcServerName, tcBasePath, tcUserName, taFileUsers
#Define VER_PLATFORM_WIN32S 0
#Define VER_PLATFORM_WIN32_WINDOWS 1
#Define VER_PLATFORM_WIN32_NT 2
Local lnmajor, lnminor, lnplatform, lnbuild
GetOSVersion(@lnmajor, @lnminor, @lnplatform, @lnbuild)
If lnplatform # VER_PLATFORM_WIN32_NT
MSB("Windows NT Required")
Return .F.
Endif
If Type('tcServerName')#'C' .or. Type('tcBasePath')#'C' .or. Type('tcUserName')#'C'
Return .F.
Endif
Local lcServerName, lcBasePath, lcUserName, lnBufferPointer
Local lnPreferedMaxLength, lnEntriesRead, lnTotalEntries
Local lnResumeHandle, lnError
Local loPointersObject
Local lnI, lcDll, lnAuser, lnPermissions, lnID
Local llContinue, lnpFileInfo, lcFileName
Local lnLocks, lcUserName
Declare INTEGER NetFileEnum IN NETAPI32 ;
STRING @ServerName, STRING @BasePath, ;
STRING @UserName, INTEGER nLevel, ;
INTEGER @BufferPointer, INTEGER PreferedMaxLength, ;
INTEGER @EntriesRead, INTEGER @TotalEntries, ;
INTEGER @ResumeHandle
Declare INTEGER NetApiBufferFree IN NETAPI32 ;
INTEGER Pointer
*-- This is the structure used by NetFileEnum
* to retrieve the information.
*typedef struct _FILE_INFO_3 {
* DWORD fi3_id;
* DWORD fi3_permissions;
* DWORD fi3_num_locks;
* LPWSTR fi3_pathname;
* LPWSTR fi3_username;} FILE_INFO_3
*-- The server name, the base path and the user name
* must be in Unicode format.
lcServerName = StrConv(StrConv(tcServerName + Chr(0), 1), 5)
lcBasePath = StrConv(StrConv(tcBasePath + Chr(0), 1), 5)
lcUserName = StrConv(StrConv(tcUserName + Chr(0), 1), 5)
*-- Allow for a very large buffer.
* If this length is not enough, the info
* will be retrieved in more than one step.
lnPreferedMaxLength = 100000000
lnResumeHandle = 0
lnEntriesRead = 0
lnTotalEntries = 0
lnBufferPointer = 0
lnAuser = 0
llContinue = .t.
Do WHILE llContinue
lnError = NetFileEnum( lcServerName, lcBasePath, lcUserName, 3, ;
@lnBufferPointer, lnPreferedMaxLength, @lnEntriesRead, ;
@lnTotalEntries, @lnResumeHandle)
If lnEntriesRead = 0
*-- There are no (more) open files.
llContinue = .f.
Endif
If lnError = 0
For lnI = 1 TO lnEntriesRead
*!* lnpFileInfo = lnBufferPointer + (lnI - 1) * 20
*!* *-- Extract the file name
*!* lcFileName = GetMemoryLPString(lnpFileInfo + 12)
*!* ? "File name:", lcFileName
*!* *-- Extract the number of locks on this file
*!* lnLocks = GetMemoryDWORD(lnpFileInfo + 8)
*!* ? "Locks:", lnLocks
*!* *-- Extract the user name that opened the file
*!* lcUserName = GetMemoryLPString(lnpFileInfo + 16)
*!* ? "User:", lcUserName
*!* *-- Extract the permissions on this file
*!* lnPermissions = GetMemoryDWORD( lnpFileInfo + 4)
*!* lnpFileInfo = lnBufferPointer + (lnI - 1) * 20
*!* *-- Extract the file name
*!* lcFileName = GetMemoryLPString(lnpFileInfo + 12)
*!* ? "File name:", lcFileName
*!* *-- Extract the number of locks on this file
*!* lnLocks = GetMemoryDWORD(lnpFileInfo + 8)
*!* ? "Locks:", lnLocks
*!* *-- Extract the user name that opened the file
*!* lcUserName = GetMemoryLPString(lnpFileInfo + 16)
*!* ? "User:", lcUserName
*!* *-- Extract the permissions on this file
*!* lnPermissions = GetMemoryDWORD( lnpFileInfo + 4)
lnpFileInfo = lnBufferPointer + (lnI - 1) * 20
lcUserName = GetMemoryLPString(lnpFileInfo + 16)
If lnAuser = 0 OR ASCAN(taFileUsers,lcUserName) = 0
lnAuser = lnAuser + 1
dimension taFileUsers(lnAuser)
taFileUsers(lnAuser) = lcUserName
Endif
Endfor
*-- Free the memory allocated by NetFileEnum
If lnBufferPointer <> 0
NetApiBufferFree(lnBufferPointer)
Endif
Else
MSB("NetFileNum Error Code: "+ALLT(STR(lnError)))
RETURN .f.
llContinue = .f.
Endif
Enddo
Endproc
*--
* Get the OS Version and platform
*--
Procedure GetOSVersion
Lparameter m.major, m.minor, m.platform, m.build
Local m.osversion
Declare GetVersionEx IN win32api String @OSVERSIONINFO
* The OSVERSIONINFO structure is 148 bytes long.
m.osversion = long2str(148) + Replicate(Chr(0), 144)
=GetVersionEx(@m.osversion)
m.major = str2long(Substr(m.osversion, 5, 4))
m.minor = str2long(Substr(m.osversion, 9, 4))
m.build = str2long(Substr(m.osversion, 13, 4))
m.platform = str2long(Substr(m.osversion, 17, 4))
m.build = BitAnd(m.build, 0xFFFF)
Endproc
*--
* Return a Unicode from a pointer to LPWString
*--
Function GetMemoryLPString
Lparameter m.nPointer, m.nPlatform
Local m.cResult, m.nLPStr, m.nslen
m.nLPStr = GetMemoryDWORD(m.nPointer)
Declare RtlMoveMemory IN Kernel32 String@ dest, Integer src, Integer nsize
Declare Integer lstrlenW IN Kernel32 Integer src
m.nslen = lstrlenW(m.nLPStr) * 2
m.cResult = Replicate(chr(0), m.nslen)
RtlMoveMemory(@m.cResult, m.nLPStr, m.nslen)
m.cResult = StrConv(StrConv(m.cResult, 6), 2)
Return m.cResult
Endfunc
*--
* Return Number from a pointer to DWORD
*--
Function GetMemoryDWORD
Lparameter m.nPointer
Local m.cstrDWORD
Declare RtlMoveMemory IN Kernel32 String@ dest, Integer src, Integer nsize
m.cstrDWORD = Replicate(chr(0), 4)
RtlMoveMemory(@m.cstrDWORD, m.nPointer, 4)
Return str2long(m.cstrDWORD)
Endfunc
*--
* Convert a Number intto a binary Long Integer
*--
Function long2str
Lparameter m.nLong
m.nLong = Int(m.nLong)
Return (chr(bitand(m.nLong,255)) + ;
chr(bitand(bitrshift(m.nLong, 8), 255)) + ;
chr(bitand(bitrshift(m.nLong, 16), 255)) + ;
chr(bitand(bitrshift(m.nLong, 24), 255)))
Endfunc
*--
* Convert a binary Long Integer into a Number
*--
Function str2long
Lparameter m.cpLong
Return (Bitlshift(Asc(Substr(m.cpLong, 4, 1)), 24) + ;
Bitlshift(Asc(Substr(m.cpLong, 3, 1)), 16) + ;
Bitlshift(Asc(Substr(m.cpLong, 2, 1)), 8) + ;
Asc(Substr(m.cpLong, 1, 1)))
Endfunc
KTB