![]() |
Tool für selektives AutoPlay? [Windows 7]
Hallo zusammen,
ihr kennt ja sicher das AutoPlay-Feature von Windows: Man steckt z.B. einen USB-Stick rein und Windows öffnet dann das (oft wenig hilfreiche, überladene) Fenster, in dem man die Auswahl hat, was ausgeführt werden soll. Mich hat dieses Feature immer genervt, da eh oft die falschen Optionen angeboten wurden, darum habe ich es abgeschaltet. Das ist aber auch nicht gänzlich optimal...ich würde es. z.B. gerne haben, dass beim Einstecken meines verschlüsselten USB-Sticks automatisch die EXE gestartet wird, die zum Login in den Stick auffordert. Diese EXE liegt aber in einer ReadOnly-Partition des Sticks, somit kann ich dort keine Autostart.ini oder dergleichen erstellen. (Edit-Info: Es handelt sich um einen "Kingston DataTraveler 5000") Lange Rede, kurzer Sinn: Kennt jemand vielleicht ein Tool, bei dem man eine solche AutoPlay-Funktionalität selektiv einstellen kann? Heisst, das Programm erkennt einen Stick und man kann für diesen Stick, wenn er das erste Mal gemountet wird, auswählen, was beim Einstecken automatisch gestartet wird. Wenn man den Stick einmal konfiguriert hat, passiert das dann in Folge automatisch (Das zuvor ausgewählte Programm wird immer gestartet, sobald man diesen Stick reinsteckt). Gibt es so etwas überhaupt? |
AW: Tool für selektives AutoPlay? [Windows 7]
Weiß nicht ob es sowas gibt, aber sollte auch nicht allzu schwer sein sich so ein Tool selbst zu schreiben :)
|
AW: Tool für selektives AutoPlay? [Windows 7]
Gute Idee, allerdings gibt es da dann doch noch ein paar Hürden für mich...Erkennen, wann ein USB-Stick gemountet wird und dann eindeutig identifizieren....mal googlen :-D
|
AW: Tool für selektives AutoPlay? [Windows 7]
![]() ![]() ![]() ![]() Das sollte helfen ;) Habe hier mal auf die schnelle einen sehr hässlichen, aber funktionierenden Code zusammengeschustert:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) ListBox1: TListBox; private { Private-Deklarationen } public procedure WMDevChange(var Msg: TMessage); message WM_DEVICECHANGE; end; var Form1: TForm1; implementation {$R *.dfm} const DBT_DEVICEARRIVAL = $8000; DBT_DEVICEREMOVECOMPLETE = $8004; { TForm1 } procedure TForm1.WMDevChange(var Msg: TMessage); var DevName: Array[0..MAX_PATH] of Char; FileSys: Array[0..MAX_PATH] of Char; SN: DWORD; DevFlags, MaxLen: DWORD; begin if Msg.WParam = DBT_DEVICEARRIVAL then begin GetVolumeInformation('G:\',@DevName[0],MAX_PATH+1,@SN,MaxLen,DevFlags,@FileSys[0],MAX_PATH+1); ListBox1.Items.Add('Laufwerk: G:'); ListBox1.Items.Add('Bezeichnung: ' + String(DevName)); ListBox1.Items.Add('Dateisystem: ' + String(FileSys)); ListBox1.Items.Add('Serien-Nr.: ' + IntToStr(SN)); end else if Msg.WParam = DBT_DEVICEREMOVECOMPLETE then ListBox1.Items.Clear; end; end. |
AW: Tool für selektives AutoPlay? [Windows 7]
Eine Alternative wäre einfach die integrierte Autoplayfunktion so anzupassen wie man es möchte statt diese abzuschalten...
Unter "Automatische Wiedergabe" finden sich in der Systemsteuerung bereits die wichtigsten Optionen. Und wenn man eigene Einträge braucht, gibt es diverse Tools dafür: ![]() |
AW: Tool für selektives AutoPlay? [Windows 7]
Danke euch vielmals!
Das hilft schonmal extrem weiter. :-) Welche Lösung ich nun nehme, zeigt, ob ich das mit dem DeviceChange auch sauber implementiert kriege oder ob ich jaenicke's Lösung für ausreichend halte. Danke aber nochmal, vor Allem auch für das Code-Schnippsel! :thumb: |
AW: Tool für selektives AutoPlay? [Windows 7]
Ok, ich habe mir mal schnell eine kleine Komponente zusammengeschustert, um ein Event zu erzeugen, wenn eine System Volume gemountet / ungemounted wird.
Wer's brauchen kann, hier der Code:
Delphi-Quellcode:
unit ehXDeviceChange;
{ ehXDeviceChange ################ Component for event notification when a system volume has been mounted or unmounted (e.g. removable drives or media) Author: blackFin Email: blackfin@elfenherz.de For: The "Delphi Praxis" community (http://www.delphipraxis.net/) Date of creation: 15.08.2011 License: Do what you want with it, but there is one thing that always makes me happy: ############################################################################## If you modify the source and / or enhance this component, pleeeease, send your modified source code back to me via email. ############################################################################## } interface uses Windows,Messages,SysUtils,Classes,Forms ; type // Events TehXDeviceMountedEvent = procedure(ADrive: Char; ADriveName: string) of object ; TehXDeviceUnmountedEvent = procedure(ADrive: Char; ADriveName: string) of object ; // Class declaration of device change notifier TehXDeviceChangeNotifier = class(TComponent) private FDriveList : array of array[0..1] of string ; FMessageHook : boolean ; FVolumesMapped : boolean ; FOnDeviceMounted : TehXDeviceMountedEvent ; FOnDeviceUnmounted : TehXDeviceUnmountedEvent ; function FDoMessageHook(var Msg: TMessage): boolean ; procedure FOnWMDeviceChange(var Msg: TMessage); function FGetVolumeName(FDrive: Char): string; protected public constructor Create(AOwner: TComponent) ; override ; destructor Destroy() ; override ; procedure CreateVolumeMapping() ; function GetVolumeName(FDrive: char): string; published property OnDeviceMounted: TehXDeviceMountedEvent read FOnDeviceMounted write FOnDeviceMounted ; property OnDeviceUnmounted: TehXDeviceUnmountedEvent read FOnDeviceUnmounted write FOnDeviceUnmounted ; end; procedure Register; implementation const DRIVE_UNKNOWN = 0; DRIVE_NO_ROOT_DIR = 1; DRIVE_REMOVABLE = 2; DRIVE_FIXED = 3; DRIVE_REMOTE = 4; DRIVE_CDROM = 5; DRIVE_RAMDISK = 6; // CONSTRUKTOR constructor TehXDeviceChangeNotifier.Create(AOwner: TComponent) ; begin inherited Create(AOwner) ; FVolumesMapped := false ; if not (csDesigning in ComponentState) then begin Application.HookMainWindow(FDoMessageHook); FMessageHook := True; self.CreateVolumeMapping() ; end; end; // DESTRUCTOR destructor TehXDeviceChangeNotifier.Destroy() ; begin SetLength(FDriveList,0) ; if FMessageHook then Application.UnhookMainWindow(FDoMessageHook); inherited Destroy() ; end; // message hook from main window function TehXDeviceChangeNotifier.FDoMessageHook(var Msg: TMessage): boolean; begin Result := False; case Msg.Msg of WM_DEVICECHANGE: begin FOnWMDeviceChange(Msg); Result := true ; end; end; end; // on device change procedure TehXDeviceChangeNotifier.FOnWMDeviceChange(var Msg: TMessage); type PDevBroadcastHdr = ^TDevBroadcastHdr; TDevBroadcastHdr = packed record dbcd_size, dbcd_devicetype, dbcd_reserved: DWORD; end; PDevBroadcastVolume = ^TDevBroadcastVolume; TDevBroadcastVolume = packed record dbcv_size, dbcv_devicetype, dbcv_reserved, dbcv_unitmask: DWORD; dbcv_flags: Word; end; function GetDrive(pDBVol: PDevBroadcastVolume): string; var i: Byte; VolumeMask: DWORD; begin case (pDBVol^.dbcv_flags) of // removable MEDIA 0: begin // todo: do something with this information end; // removable DRIVE 1: begin // todo: do something with this information end; end; VolumeMask := pDBVol^.dbcv_unitmask; for i := 0 to 25 do begin if (VolumeMask and 1) = 1 then Result := Char(i + Ord('A')) + ': '; VolumeMask := VolumeMask shr 1; end; end; var Drive,DriveName: String; begin case Msg.wParam of // drive has been mounted $8000: if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = $0002 then begin Drive := GetDrive(PDevBroadcastVolume(Msg.lParam)); DriveName := FGetVolumeName(Drive[1]) ; self.CreateVolumeMapping() ; if Assigned(FOnDeviceMounted) then FOnDeviceMounted(Drive[1],DriveName) ; end; // drive has been unmounted $8004: if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = $0002 then begin Drive := GetDrive(PDevBroadcastVolume(Msg.lParam)); if Assigned(FOnDeviceUnmounted) then FOnDeviceUnmounted(Drive[1],self.GetVolumeName(Drive[1])) ; self.CreateVolumeMapping() ; end; end; end; // get the name of a volume (internally, from sytem) function TehXDeviceChangeNotifier.FGetVolumeName(FDrive: Char): string; var max, Flags: DWORD; Buf: array [0..MAX_PATH] of Char; SN: DWORD; FileSys: Array[0..MAX_PATH] of Char; begin try GetVolumeInformation(PChar(string(FDrive + ':')), @Buf[0], sizeof(Buf), @SN, max, Flags, @FileSys, 0); Result := Buf; except result := ''; end; end; // get the name of a volume (from volume mapping) function TehXDeviceChangeNotifier.GetVolumeName(FDrive: char): string; var i: Integer ; begin if (not FVolumesMapped) then self.CreateVolumeMapping() ; Result := '' ; for i := 0 to High(FDriveList) do begin if FDriveList[i][0] = FDrive then begin Result := FDriveList[i][1] ; break ; end; end; end; // get all currently available volume names procedure TehXDeviceChangeNotifier.CreateVolumeMapping() ; var r: LongWord; Drives: array[0..128] of char; pDrive: PChar; begin SetLength(FDriveList,0) ; r := GetLogicalDriveStrings(SizeOf(Drives), Drives); if r = 0 then Exit; if r > SizeOf(Drives) then raise Exception.Create(SysErrorMessage(ERROR_OUTOFMEMORY)); pDrive := Drives; while pDrive^ <> #0 do begin case GetDriveType(pDrive) of DRIVE_FIXED, DRIVE_CDROM, DRIVE_REMOVABLE: begin // Anyone that uses still floppy drives? No, Tux SysAdmins, not you! :-) // Well, I've skipped reading the mapping on floppy drives A:\ and B:\ because reading the volume names of floppy drives is sooo slow :-( // Unfortunately, floppy drives have no own DriveType, they are listed as DRIVE_REMOVABLE, so extra handling of those is not clearly possible. // (comment out next line if you want to enable volume mapping on floppy dives A:\ and B:\, too) if ( (pDrive <> 'A:\') and (pDrive <> 'B:\') ) then begin SetLength(FDriveList,High(FDriveList)+2) ; FDriveList[High(FDriveList)][0] := string(pDrive[0]) ; FDriveList[High(FDriveList)][1] := self.FGetVolumeName(pDrive[0]) ; end; end; end; Inc(pDrive,4); end; FVolumesMapped := true ; end; // Register component in ehX Toolbar procedure Register; begin RegisterComponents('ehX', [TehXDeviceChangeNotifier]); end; end. |
AW: Tool für selektives AutoPlay? [Windows 7]
@ehX: könnte man diese Komponente dahin gehend anpassen, dass die Autorun-Funktion von optischen Laufwerken (CD/DVD/BD) unterbunden wird? Erkannt wird der Gerätewechsel ja irgendwie, aber wie dann Autorun verhindern?
|
AW: Tool für selektives AutoPlay? [Windows 7]
@devidespe:
Da AutoPlay eine globale Funktion des Betriebssystems ist, die nicht an ein Programm gebunden ist, kann das ein einzelnes Programm AFAIK nicht verhindern. Die Komponente reagiert ja nur auf eine Device-Change Message des OS, kann sich aber nicht "rein-hooken". Allerdings kann man AutoPlay ja in Windows generell abschalten und dann nur noch die Komponente verwenden. Der Device-Change Event wird ja auch erzeugt, wenn AutoPlay in Windows deaktiviert ist. |
AW: Tool für selektives AutoPlay? [Windows 7]
Autoplay in Windows abzuschalten, erfordert einen Neustart - den ich leider nicht durchführen kann. Es gibt hier im Forum verschiedene Lösungen, die allesamt auf QueryCancelAutoplay basieren, das funzt allerdings ab Windows 7 nicht mehr.
Die Alternative iQueryCancelAutoplay erfordert wiederum einen COM Server und ich habe mich da noch nicht drangewagt. Deswegen dachte ich, dass die Komponente evtl. helfen kann... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz