Link to home
Start Free TrialLog in
Avatar of jannea
jannea

asked on

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
Avatar of vorlon
vorlon

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.
Avatar of jannea

ASKER

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
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
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.


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
Avatar of jannea

ASKER

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
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?
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.
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...
Avatar of jannea

ASKER

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
Avatar of jannea

ASKER

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
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.
Avatar of jannea

ASKER

Sorry, Vorlon

I get the same result whith:

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

/Janne
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.


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...
Avatar of jannea

ASKER

Still waiting for a answer...

/Janne


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.
Avatar of jannea

ASKER

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
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.
Avatar of jannea

ASKER

Vorlon:

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

/Jannea
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.
Avatar of jannea

ASKER

Vorlon:

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

/Janne
Avatar of jannea

ASKER

Adjusted points to 100
ASKER CERTIFIED SOLUTION
Avatar of y96andha
y96andha

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jannea

ASKER

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
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)


Avatar of jannea

ASKER

Tack för det, det var nog bättre.

Vi hörs, Janne.a@mailbox.swipnet.se