HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Milyen alkalmazásokat indít el a felhasználó?


Példaprogram letöltése

5152 bájt

Készítünk most egy olyan alkalmazást, melynek segítségével valós időben követhetjük, hogy a felhasználó milyen alkalmazásokat indít el, milyen dokumentumokat nyit meg. Programunk ezeket akár naplózhatja, de akár meg is akadályozhatja, hogy bizonyos programokat egy adott felhasználó elindíthasson.
Megvalósításhoz meg kell ismernünk, hogy miként hozhatunk létre a Visual Studio.NET-el COM DLL-t, melyben implementálunk egy Windows interfészt.

Ez az interfész a Windows Shell által nyújtott IShellExecuteHook. Ezt felhasználva elérhetjük azt, hogy ha a rendszerben bármely program meghívja a ShellExecute, vagy a ShellExecuteEx függvényt és ezzel elindítana egy új alkalmazást, akkor erről értesülhet a mi programunk is. Mivel ez az értesítő az elindítandó program futtatása előtt történik, így lehetőségünk van arra is, hogy a futtatást megakadályozzuk.
Ha a Start menü Futtatás (Run) parancsát használjuk, vagy csak a Windows Intézőben rákattintunk egy programra futtatás céljából, akkor a ShellExecuteEx kerül meghívásra és így értesülhet saját alkalmazásunk. Ha a felhasználó az Intézőben mondjuk egy DOC kiterjesztésű állományra kattint, akkor is a ShellExecuteEx-en keresztül történik az indítás, így még a regisztrált típusú dokumentumok megnyitásáról is tudomást szerezhetünk.
A megvalósításhoz készítenünk kell egy DLL-t, melyben implementáljuk az IShellExecuteHook interfészt. Hozzunk hát létre egy új Class Library típusú projektet.
Ezt COM szerverként szeretnénk üzemeltetni, így a megfelelő regisztrációhoz válasszuk ki a Solution Explorer-ben a ShellExecuteHook nevű projektünket, majd jobb gomb és Properties menüpont. A megjelenő ablakban válasszuk a Configuration Properties - Build elemet. Ekkor elérhetővé válik a Register for COM interop tulajdonság, melyet állítsunk igazra.
Következő lépés, hogy deklaráljuk az IShellExecuteHook interfészt. Ezt nekünk kell megtennünk, mivel nincs olyan assembly, melyre hivatkozhatnánk referenciaként, viszont ismerjük az IShellExecuteHook interfész GUID azonosítóját, amely 000214FB-0000-0000-C000-000000000046 értékű.
Létrehozunk tehát egy IShellExecuteHook nevű interfészt. Itt használnunk kell a ComImport attribútumot, hogy a fordító tudtára adjuk, hogy mi is a szándékunk. Megadjuk továbbá az interfész típusát, mely az IUnknown-ból származik, végül a Guid attribútumba azt a GUID számot, mely egyértelműen azonosítja, hogy az IShellExecuteHook-ot szeretnénk használni.
<ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214FB-0000-0000-C000-000000000046")> _
Public Interface IShellExecuteHook
Egyszerű a továbbiakban a helyzetünk, mert az IShellExecuteHook interfésznek csupán egyetlen függvénye van, amely Execute névre hallgat. A függvény megadása előtt használjuk a PreserverSig attribútumot, mely elnyomja a HRESULT használatát.
Az Execute függvény egy SHELLEXECUTEINFO nevű struktúrájú paramétert tartalmaz, melyből megtudható, hogy milyen állományt is szeretne a felhasználó elindítani és azt is milyen paraméterekkel.
  <PreserveSig()> _
  Function Execute(ByVal sei As SHELLEXECUTEINFO) As Integer
End Interface 'IShellExecuteHook
Mivel SHELLEXECUTEINFO struktúra a .NET Framework-ben nem létezik, csak a Windows API-ben, így ennek megfelelőjét is létre kell hoznunk.
<StructLayout(LayoutKind.Sequential)> _
Public Class SHELLEXECUTEINFO
  Public cbSize As Integer
  Public fMask As Integer
  ...
Speciális típusoknál, mint a Windows-ban adott LPCTSTR a MarshalAs attribútumot használva elérhetjük azt, hogy az adott mezőt string típusként érhessük el.
  <MarshalAs(UnmanagedType.LPWStr)> _
  Public lpVerb As String
  ...
Most már adott az interfész, így hozzáláthatunk osztályunk megvalósításához. Szükségünk lesz egy saját GUID számra, a DLL-ünk regisztrálásához. Új GUID-ot a Visual Studio.NET Tools menü Create GUID menüpontjával kaphatunk. A megjelenő ablakban válasszuk a Registry Format-ot, majd a Copy gombbal másoljuk az eredményt a vágólapra. Az ablak bezárásával beilleszthetjük a kapott számot a Guid attribútumba.
További attribútum a ComVisible, melynél igaz értéket kell megadnunk, hogy a Class1 osztályunk COM objektumként regisztrálásra kerüljön.
<Guid("88669C52-67BB-46FB-92B2-41B6E30CC24F"), ComVisible(True)> _
Public Class Class1
Most már jöhet az Execute függvény implementálása. Tudjuk tehát, hogy az Execute akkor kerül meghívásra, amikor bármely alkalmazás a ShellExecute, illetve a ShellExecuteEx függvényt hívja meg. Paramétereként megkapjuk a két függvény hívásakor megadott paramétereket, így ezeket felhasználva megtudhatjuk, hogy melyik alkalmazás kerül elindításra.
Ha szeretnénk megakadályozni egy-egy alkalmazás futtatását, akkor a függvény visszatérési értékének adjunk nullát. Mellékelt példánkban, ha azt tapasztaljuk, hogy a felhasználó a Számológépet (calc.exe) szeretné elindítani, akkor ezt megakadályozzuk.
Hogy alkalmazásunk működését szemléltessük, minden programindítás előtt egy üzenetablakban megjelenítjük a futtatandó programot. Ezen ablak bezárása után kerül csak elindításra az adott alkalmazás.
  Public Function Execute(ByVal sei As SHELLEXECUTEINFO) As Integer Implements IShellExecuteHook.Execute
    MessageBox.Show("Futtatandó: " + sei.lpFile, "Software Online")
    If sei.lpFile.ToLower() = "calc.exe" Then
      Return 0
    Else
      Return 1
    End If
  End Function 'Execute
A DLL ezzel készen is van, de működéséhez elengedhetetlen még két lépés: az egyik a DLL regisztrációja, melyhez a Register for COM interop igazra állításával már gondoskodtunk, a másik egy speciális Windows regisztrációs adatbázis-bejegyzés. A DLL regisztrációval is gond lehet, ha az alkalmazást nem azon a gépen regisztrálnánk, ahol fejlesztettük és a másik gépen nem áll rendelkezésre a Visual Studio.NET. Ekkor a .NET Framework-ben meglévő RegAsm segédprogramot kell használnunk ahhoz, DLL-ünk regisztrációja megtörténjen.
A másik speciális bejegyzés arról értesíti a Windows-t, hogy a ShellExecute, illetve a ShellExecuteEx meghívása esetén van egy olyan alkalmazás, melyet értesíteni kell. Ehhez a HKEY_LOCAL_MACHINE alá a Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks címen egy új értéket kell elhelyezni, mely nem más, mint a DLL-ben létrehozott Class1 osztályunk GUID azonosítója.
A regisztrációs adatbázis módosítását elvégezhetnénk manuálisan is, de rábízhatjuk a DLL-ünkre is ezt a feladatot. Amikor a DLL regisztrálásra kerül (akár a Visual Studio.NET, akár a RegAsm által), ha van olyan statikus függvénye a DLL-nek, melyet megjelöltünk a ComRegisterFunctionAttribute attribútummal, akkor az meghívásra kerül. Itt elvégezhetjük azokat a tevékenységeket, melyeket a DLL regisztrálásánál szeretnénk megtenni.
  <ComRegisterFunctionAttribute()> _
  Shared Sub RegisterServer(ByVal t As Type)
    Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks", True)
    rk.SetValue(clsId, "Software Online Shell Extension")
    rk.Close()
  End Sub 'RegisterServer
Ehhez hasonlóan lehetőségünk van a regisztráció megszüntetésekor is automatikusan lefuttatni egy saját függvényt, melyet a ComUnregisterFunctionAttribute attribútummal jelölünk meg. Fontos, hogy ez a függvény is statikusként legyen deklarálva.
  <ComUnregisterFunctionAttribute()> _
  Shared Sub UnregisterServer(ByVal t As Type)
    Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks", True)
    rk.DeleteValue(clsId)
    rk.Close()
  End Sub 'UnregisterServer
Ezzel készen is lennénk. Ha a mellékelt példa DLL-je regisztrálva van, akkor ne felejtsük el, hogy egyetlen alkalmazást sem tudunk elindítani addig, amíg a DLL által megjelenített dialógusablakot be nem zárjuk, mely minden program indításkor megjelenik.
Fontos tudnivaló még az is, hogy az alkalmazásunkat az Explorer.exe fogja, így azt megváltoztatni (újra fordítani) nem tudjuk. Megoldásként jelentkezzünk ki és ismét be a rendszerbe.

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |