GetModuleHandle & GetModuleUsage

Hello !

Is it anyone who can help me whith this:
I like to know if a file is running on the machine.
In VB3 i did use it like this but it won´t work now in 32-bit.  
    X = GetModuleHandle("C:\Windows\System\tapiexe.exe") X = GetModuleUsage(X)
If X <> 0 Then  'The Program runs
   
Do anyone know how to find out that a file runs in 32-bit ?
Janne Andersson, Nyköping Sweden

Mail:         janne.a@mailbox.swipnet.se
LVL 1
janneaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

vorlonCommented:
Jannea,
Here's one way that will work. Cycle throught the task list. As you do, check the name of the file of the current application with the name of the file you're looking for. Here's an example.

This example checks to see of c:\windows\calc.exe (Calculator) is running.

Sub Command1_Click ()
    Const neededFile = "c:\windows\calc.exe"
    Dim hInstance As Variant, hWnd As Variant
    Dim fname As String
    Dim x As Integer

    'get first window
    hWnd = GetWindow(Form1.hWnd, GW_HWNDFIRST)
    Do
        'get handle of window
        hInstance = GetWindowWord(hWnd, GWW_HINSTANCE)

        'get name of exe file running
        fname = String(256, 0)
        x = GetModuleFileName(hInstance, fname, Len(fname))

        'compare running app with what were looking for
        If LCase$(Left$(fname, x)) = LCase$(neededFile) Then
            'yes, the exe file were interested in is running
            MsgBox neededFile & " found"
        End If

        'get the next window from the task list
        hWnd = GetWindow(hWnd, GW_HWNDNEXT)

    'keep looping until there's no more app's in the task list
    Loop Until hWnd = 0
End Sub


Hope this helps.
0
janneaAuthor Commented:
Hello Vorlon, and thanks for your answer !

But i can´t find the value for the constant GWW_HINSTANCE.
so i did use the GWL_HINSTANCE = -6 instead, and
hwnd = GetWindow(Screen.ActiveForm.hwnd, GW_HWNDFIRST)
I don´t know if this works but the only application i can se running is VB5 the one i run it from.
What can be wrong i have several app´s running.

/Janne
0
y96andhaCommented:
Testa GetWindowLong istället för GetWindowWord och se om det fungerar. Jag tror det är det L respektive W står för i GWL_HINSTANCE.

/ Andreas
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

vorlonCommented:
Jannea,
You use GW_HWNDFIRST for only the first call. All subsequent calls to GetWindow() you have to use GW_HWNDNEXT. Also, I used the handle of the main window in my application. I don't know if using Screen.ActiveForm.hwnd works simply because the active window can be a dialog box. GetWindow usually only returns parent windows unless you specifically ask for child windows.

Try that and see how it works.
Hope this helps.


0
y96andhaCommented:
Jodå, nu har jag testat det, och det är minsann lösningen på problemet. Får jag nån poäng för det? :-)

/ Andreas
0
janneaAuthor Commented:
This time i get several files by changing to
GetWindowLong(hwnd, GWL_HINSTANCE)
as Andreas comment (Tack du...).
But... i can´t understand what i get oute of this
it lists same file several times, some are blank and it seems
to be only the files VB5 uses.
I even run several exe´s but i can´t see them in the loop.
Send the result of my loop and my code.

This is the result of the my loop line by line:

C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE


C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE

C:\PROGRAM\VANLIGA FILER\MICROSOFT SHARED\VBA\MSO97RT.DLL
C:\PROGRAM\VANLIGA FILER\MICROSOFT SHARED\VBA\MSO97RT.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VBA5.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VBA5.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\WINDOWS\SYSTEM\RPCRT4.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\VB5\VBA5.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\MSVBVM50.DLL
C:\WINDOWS\SYSTEM\OLEAUT32.DLL
C:\WINDOWS\SYSTEM\MSVBVM50.DLL
C:\WINDOWS\SYSTEM\RPCRT4.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\MSVBVM50.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLEAUT32.DLL
C:\WINDOWS\SYSTEM\MSVBVM50.DLL
C:\WINDOWS\SYSTEM\RPCRT4.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\VB5\VB5.EXE
C:\PROGRAM\VANLIGA FILER\MICROSOFT SHARED\VBA\MSO97RT.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\SHELL32.DLL
C:\WINDOWS\SYSTEM\SHELL32.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE


C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\WINDOWS\SYSTEM\SHELL32.DLL
C:\WINDOWS\SYSTEM\SHELL32.DLL
C:\WINDOWS\SYSTEM\SHELL32.DLL
C:\WINDOWS\SYSTEM\SHELL32.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE




C:\VB5\VB5.EXE
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\WINDOWS\SYSTEM\OLE32.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE
C:\WINDOWS\SYSTEM\MSVBVM50.DLL
C:\WINDOWS\SYSTEM\MSVBVM50.DLL
C:\VB5\VB5.EXE
C:\VB5\VB5.EXE

104 lines.




Sub KörsFil()
Const neededFile = "c:\windows\calc.exe"
Dim hInstance As Variant, hwnd As Variant
Dim fname As String
Dim X As Integer
Dim Y%, s$

'get first window
    s = "This is the result of the my loop:" & vbCrLf
    hwnd = GetWindow(Screen.ActiveForm.hwnd, GW_HWNDFIRST)
    Do
'get handle of window
         hInstance = GetWindowLong(hwnd, GWL_HINSTANCE)
'get name of exe file running
        fname = String(256, 0)
        X = GetModuleFileName(hInstance, fname, Len(fname))
        Y = Y + 1
        s = s & fname & vbCrLf
'compare running app with what were looking for
        If LCase$(Left$(fname, X)) = LCase$(neededFile) Then
'yes, the exe file were interested in is running
            MsgBox neededFile & " found"
        End If
'get the next window from the task list
        hwnd = GetWindow(hwnd, GW_HWNDNEXT)

'keep looping until there's no more app's in the task list
    Loop Until hwnd = 0
    s = s & Y & " st instanser." & vbCrLf
    MsgBox s
End Sub

Any new ideas ??????

/Janne
0
y96andhaCommented:
Verkar som du har rätt i det. Jag testade bara och konstaterade att det dök upp annat än VB i rutan. Vad är det för program du ska kolla efter? Skulle du kunna kolla på något annat än exe-filens namn, t.ex. namn på fönster eller fönsterklass?
0
y96andhaCommented:
Här är en funktion som nog kan användas: CreateToolhelp32Snapshot

Tyvärr har jag mycket att göra just nu, så jag kan inte skriva ner nåt exempel, och jag är inte helt säker på att den fungerar med VB, men det kan kanske vara värt ett försök.
0
vorlonCommented:
Y96andha,
What language are you speacking. I'm getting something that is not english.

Jannea,
I'll confirm the code again. This time I'll use my VB4 compiler. I'll let you know if I get the same problem as you...
0
janneaAuthor Commented:
Re: Andreas (y96andha)

It would be nice if you could give me codesample on
CreateToolhelp32Snapshot, so i can see if that works better
then the sample above.
If not Vorlon can give me a solotion on my problem.
I write in english so evev Vorlon can understand.

/Janne
0
janneaAuthor Commented:
RE Vorlon
y96andha have givenen me comments in Swedish.

I use VB5 and i just like to know if a specific file is
loaded *.exe or *.dll as you can see above i don´t get
what i like to get oute of the loop.

/Janne
0
vorlonCommented:
Jannea,
Swedish? Pretty interesting...

Anyway, found some information for you. I don't have a 32 bit compiler with me at this time so you'll have to try this yourself or wait until I get home tonight.

hWnd = GetWindow(Form1.hWnd, GW_HWNDFIRST)
In my answer above I'm using this line of code to get the first top level window. Instead of using Form1.hWnd, use the handle of the desktop window and get it's child windows. Like this:

hWnd = GetDesktopWindow()
hWnd = GetWindow(hWnd,GW_CHILD)
'or in one line
'hWnd = GetWindow(GetDesktopWindow(),GW_CHILD)
Do
 ...
Loop


This came straight out of "Visual Basic Programmer's Guide to the Win32 API" by Daniel Appleman, Chapter 5: Windows Control and Information Functions, page 180-181. It states:

"...the first of several methods for enumerating windows. It starts by obtaining the handle of the desktop window - the window that represents the entire screen. All windows in the system are considered children of the desktop - which is not the same as saying that they are child windows. It's best to think of the desktop window as a special window that provides certain special capabilities, one of which is to help you enumerate other windows in the system."

I'll confirm this at home. In the mean time, hope this helps.
0
janneaAuthor Commented:
Sorry, Vorlon

I get the same result whith:

hWnd = GetDesktopWindow()
hWnd = GetWindow(hWnd,GW_CHILD)

/Janne
0
y96andhaCommented:
This time in English so everyone can read it :-)

OK, I've modified your code in the following, vorlon:

Private Sub Command1_Click()
Cls
    Dim hInstance As Variant, hwnd As Variant, hModule As Variant
    Dim fname As String
    Dim txt As String
    Dim x As Integer

    'get first window
    hwnd = GetWindow(Form1.hwnd, GW_HWNDFIRST)
    Do
    'get handle of window
    hInstance = GetWindowLong(hwnd, GWL_HINSTANCE)
    hModule = GetClassLong(hwnd, GCL_HMODULE)
    txt = String(256, 0)
   
    'get name of exe file running
    fname = String(256, 0)
    x = GetModuleFileName(hModule, fname, Len(fname))
   
    GetWindowText hwnd, txt, 256
   
    Print hModule; " "; hInstance; " FN:"; Left$(fname, InStr(fname, Chr(0)) - 1); " T:"; Left$(txt, InStr(txt, Chr(0)) - 1)

    'get the next window from the task list
    hwnd = GetWindow(hwnd, GW_HWNDNEXT)

    'keep looping until there's no more app's in the task list
    Loop Until hwnd = 0
End Sub

When you use this code you will see that there are lots of windows for which no exe is found. An example is:

1901068288   1901068288  FN: T:Experts Exchange(sm):  Visual Basic Question - Microsoft Internet Explorer
 1666711552   1666711552  FN: T:Internet Explorer

The Win32 documentation says:

The GetModuleFileName function retrieves the full path of the module associated with a handle returned by GetModuleHandle or LoadLibrary.

The GetModuleHandle function returns a module handle for the specified module if the file has been mapped into the address space of the calling process.


From this I draw a conclusion: GetModuleFileName might not work with modules loaded in other address spaces than that of the calling process.

If that is the case, then I suggest an alternative method, using a function named CreateToolhelp32Snapshot together with Process32First and Process32Next. I am not sure whether this will work under Windows NT, because it is listed under Windows 95 features, but it is the best function I've found yet.

Unfortunately I've never used any of these functions, so I figured that if someone else has, he/she could probably more easily create an example program. I have an example in C if someone's interested.


0
vorlonCommented:
Jannea,
SORRY. It seems that win32 architecture prevents you from finding out the name (exe of dll) of a module asside from that of the current application. This would explay why you're getting a lot of Visual Basic files.

I placed you're question on a the visual basic news group. As soon  as I know something I'll pass it on to you?

(But if code in vb3, the previous answer would work, ha ha)

Again, sorry. I'll try to get you an answer as soon as possible...
0
janneaAuthor Commented:
Still waiting for a answer...

/Janne


0
y96andhaCommented:
Tja, vorlon har ju svarat på frågan, så för inga poäng alls, eller "bara" 50 är det lite mycket jobb. Men jag skulle kunna titta lite på det.
0
janneaAuthor Commented:
Andreas:
Har inte fattat vad som händer när man kommer till ett läge där det blir låst som i denna fråga.
För att kasta ut frågan på nytt, och vad är rimligt att ge för bedömning till Vorlon ?

Har ju fortfarande inget som funkar...

/Janne
0
y96andhaCommented:
För att kasta ut frågan på nytt och låta någon annan svara så ska du välja grade F, då kommer den åter att hamna uppe bland obesvarade frågor. Men vorlon verkar ju jobba på att få ett svar från newsgrupperna, så det kan hända att han löser det.
0
janneaAuthor Commented:
Vorlon:

Do you think you can get me some answer or should
i let someone else to try to answer it  ?

/Jannea
0
vorlonCommented:
Jannea,
Unfortunatly, I'm still stuck. Give it to someone who can: I too would like to know how to get around the Different Module structure... I'm still working on it but might take a while.

Sorry.
0
janneaAuthor Commented:
Vorlon:

Thanks anyway and welcome to try again.
I think i have to increase the points...

/Janne
0
janneaAuthor Commented:
Adjusted points to 100
0
y96andhaCommented:
Detta är en lösning som kräver Windows 95:

Private Const TH32CS_SNAPPROCESS = &H2
Private Const MAX_PATH = 260
Private Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long
    th32DefaultHeapID As Long
    th32ModuleID As Long
    cntThreads As Long
    th32ParentProcessID As Long
    pcPriClassBase As Long
    dwFlags As Long
    szExeFile As String * MAX_PATH
End Type
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal dwFlags As Long, ByVal PID As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapShot As Long, pe32 As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapShot As Long, pe32 As PROCESSENTRY32) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Sub Command1_Click()
    Cls
    Dim hSnapShot As Long: hSnapShot = 0
    Dim pe32 As PROCESSENTRY32

    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
    If hSnapShot = -1 Then
        MsgBox "fel"
        Exit Sub
    End If
   
   
    pe32.dwSize = Len(pe32)
   
    If Process32First(hSnapShot, pe32) Then
        Do
            Print pe32.szExeFile
        Loop While Process32Next(hSnapShot, pe32)
    Else
        MsgBox "ingen process32first!"
    End If

    CloseHandle hSnapShot
End Sub



0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
janneaAuthor Commented:
Tack för detta Andreas, det funka bra !

Vet du något smart sätt att ta bort Nulltecknen föresten ?
Det jag gjort nu verkar klumpigt !

     Do
            sE = pe32.szExeFile
            For X = 1 To Len(sE)
                If Mid$(sE, X, 1) = vbNullChar Then
                    sE = Left$(sE, X - 1): Exit For
                End If
            Next
            s = s & sE & vbCrLf
      Loop While Process32Next(hSnapShot, pe32)

Tror jag har gjort på något annat sätt tidigare men kommer inte ihåg hur. Det funkar ju inte med Trim.

"Jag tänkte som en bonus för jag gav dig Grade A."

/Janne
0
y96andhaCommented:
Jag brukar köra nåt i stil med detta. Inskrivet från minnet, men jag tror det funkar.

If Instr(pe32.szExeFile,chr(0)) Then
          sE=left$(pe32.szExeFile, Instr(pe32.szExeFile,chr(0))-1)
Else
          sE=pe32.szExeFile
End If

Om man vet att det är nulltecken i den så räcker
          sE=left$(pe32.szExeFile, Instr(pe32.szExeFile,chr(0))-1)


0
janneaAuthor Commented:
Tack för det, det var nog bättre.

Vi hörs, Janne.a@mailbox.swipnet.se
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.