![]() |
Das Handle ist ungültig
Wie kann ich das beheben bzw. auf was muss ich achten?
Ich starte einen Stream vom Internet über den IE11 anschließend führe ich TAudioVolume aus. Bei normalen Prozessen ermittelt über die PID gibt es kein Problem. Aber wenn hier die Session erstellt und die Abfrage über den Prozess läuft bekomme ich oben genannte Fehlermeldung. Was kann man machen? Das selbe Problem habe ich auch wenn die Sidebar.exe erkannt wird.
Delphi-Quellcode:
FAudioSessionList[Index].SessionGuid := GroupGuid;
HR := SessionControl2.GetDisplayName(pDisplayName); if Succeeded(HR) then begin FAudioSessionList[Index].DisplayName := pDisplayName; if AudioSessionInfo(Index).DisplayName = '' then FAudioSessionList[Index].DisplayName := GetBaseNameFromPID(PID);
Delphi-Quellcode:
Siehe shot! Das wird angezeigt.
function TAudioVolume.GetBaseNameFromPID(const PID: DWORD): string;
var hProcess: THandle; path: array [0 .. MAX_PATH - 1] of WChar; ErrorTxt : array [0..500] of char; begin hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID); if hProcess <> 0 then try if GetModuleBaseName(hProcess, 0, path, MAX_PATH) = 0 then begin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, GetLastError, 0, ErrorTxt, 500, nil); ShowMessage(ErrorTxt); //RaiseLastOSError; end; Result := path; finally CloseHandle(hProcess) end else RaiseLastOSError; end; Aber ich kann den Prozess steuern also die Lautstärke desselben. Zudem bekomme ich so gut wie nie den DisplayName und den IconPath. Eigentlich müsste der DisplayName wie beim Pic stream.png sein. gruss |
AW: Das Handle ist ungültig
iexplore.exe besteht ja MINDESTENS aus zwei Process-Instanzen, wenn ich ihn bei mir hier starte und sonst nichts mache (laut Task-Manager).
Probiere doch mal die andere PID aus. |
AW: Das Handle ist ungültig
Zitat:
Danke. Auf der anderen seite wie soll ich den anderen ausprobieren ? Da habe ich keinen Einfluss drauf es wird die Session initialisiert die in dem Moment Sound wieder gibt! gruss |
AW: Das Handle ist ungültig
Versuch mal anstatt GetModuleBaseName die Funktion GetProcessImageFileNameW.
Beispiel:
Delphi-Quellcode:
program Project3;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Winapi.Windows, PsAPI; function GetProcessImageFileNameW(hProcess: THandle; lpBaseName: LPCWSTR; nSize: DWORD): DWORD; stdcall; external 'PSAPI.dll'; function GetBaseNameFromPID(const PID: DWORD): string; var hProcess: THandle; LModule: HMODULE; path: array [0 .. MAX_PATH - 1] of WideChar; ErrorTxt: array [0 .. 500] of WideChar; begin hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID); if hProcess <> 0 then try LModule := 0; path := ''; // if GetModuleBaseName(hProcess, LModule, path, MAX_PATH) = 0 then if GetProcessImageFileNameW(hProcess, path, MAX_PATH) = 0 then begin ErrorTxt := ''; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, GetLastError, 0, ErrorTxt, 500, nil); Writeln(ErrorTxt); // RaiseLastOSError; end; Result := path; finally CloseHandle(hProcess) end else RaiseLastOSError; end; var gPID: DWORD; gName: string; begin try while True do begin Writeln('Bitte PID eingeben'); Readln(gPID); gName := GetBaseNameFromPID(gPID); Writeln(gName); end; except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); Readln; end; end; end. |
AW: Das Handle ist ungültig
Danke damit funktioniert es ;)
Aber! Zitat:
Verstehe nicht das da nie was ankommt. gruss |
AW: Das Handle ist ungültig
Wie machste das denn?
:glaskugel: Glaskugel sagt: Ohne genauen Quelltext keine Aussage! :glaskugel: |
AW: Das Handle ist ungültig
Zitat:
Delphi-Quellcode:
HR := SessionControl2.GetDisplayName(pDisplayName);
pDisplayName ist PWideChar und sollte den DisplayNamen zurück liefern tut er aber nicht. Bei keiner Anwendung. Wenn dieser leer ist erzwinge ich ihn das hat aber zur folge des er nicht korrekt ist. gruss |
AW: Das Handle ist ungültig
Was ist SessionControl2? Wo kommt es her? Wie wird es erzeugt? Was ist der Datentyp? Ist das ein Interface? Wie ist die Definition des Interfaces?
|
AW: Das Handle ist ungültig
Zitat:
Delphi-Quellcode:
unit AudioSessionControl;
interface uses Windows, Messages, Classes, AudioSessionEvents; const IID_IAudioSessionControl: TGUID = '{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}'; type IAudioSessionControl = interface(IUnknown) ['{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}'] function GetState(out pRetVal: uint): HResult; stdcall; function GetDisplayName(out pRetVal: LPWSTR): HResult; stdcall; function SetDisplayName(Value: LPCWSTR; EventContext: pGuid): HResult; stdcall; function GetIconPath(out pRetVal: LPWSTR): HResult; stdcall; function SetIconPath(Value: LPCWSTR; EventContext: pGuid): HResult; stdcall; function GetGroupingParam(pRetVal: pGuid): HResult; stdcall; function SetGroupingParam(OverrideValue, EventContext: pGuid): HResult; stdcall; function RegisterAudioSessionNotification(const NewNotifications: IAudioSessionEvents) : HResult; stdcall; function UnregisterAudioSessionNotification(const NewNotifications: IAudioSessionEvents) : HResult; stdcall; end; implementation end.
Delphi-Quellcode:
unit AudioSessionControl2;
interface uses Windows, Messages, Classes, AudioSessionControl; const IID_IAudioSessionControl2: TGUID = '{bfb7ff88-7239-4fc9-8fa2-07c950be9c6d}'; type IAudioSessionControl2 = interface(IAudioSessionControl) ['{bfb7ff88-7239-4fc9-8fa2-07c950be9c6d}'] function GetSessionIdentifier(out pRetVal: LPWSTR): Hresult; stdcall; function GetSessionInstanceIdentifier(out pRetVal: LPWSTR): Hresult; stdcall; function GetProcessId(out pRetVal: DWord): Hresult; stdcall; //indicates whether the session is a system sounds session. function IsSystemSoundsSession(): Hresult; stdcall; //S_OK = The session is a system sounds session. //S_FALSE = The session is not a system sounds session. function SetDuckingPreference(const optOut: Boolean): Hresult; stdcall; //A BOOL variable that enables or disables system auto-ducking. end; implementation end.
Delphi-Quellcode:
gruss
SessionControl2: IAudioSessionControl2;
.... HR := AudioDevice.Activate(IID_IAudioSessionManager2, CLSCTX_ALL, nil, IUnknown(SessionManager2) ); if Succeeded(HR) then begin HR := SessionManager2.GetSessionEnumerator(pEnumerator); if Succeeded(HR) then begin HR := pEnumerator.GetSession(Index, SessionControl); if Succeeded(HR) then begin HR := SessionControl.QueryInterface(IAudioSessionControl2, SessionControl2); if Succeeded(HR) then |
AW: Das Handle ist ungültig
Zusatzfrage: Welchen Wert hat HR?
Delphi-Quellcode:
HR := SessionControl2.GetDisplayName(pDisplayName);
|
AW: Das Handle ist ungültig
Zitat:
gruss |
AW: Das Handle ist ungültig
Das mit dem unvollständigen Quelltext-Schnipseln ist mir so zu mühselig.
Lade bitte ein kleines Konsolenprojekt mit allen notwendigen Units und Dateien als ZIP-Archiv hoch. |
AW: Das Handle ist ungültig
Zitat:
Schicke ihn dir aber gerne zu wenn ich eine Mail hätte. gruss |
AW: Das Handle ist ungültig
Das ist ein Forum.
Man stellt öffentlich Fragen und erhält öffentlich Antworten. Es hätte keinen Sinn für nachfolgende Programmierergenerationen, wenn die eventuell folgende Lösung nur noch per internen Mailverkehr abläuft. Ein kleines Beispielprogramm mit allen notwendigen Units wird ja möglich sein. Anders machen das andere User ja auch nicht, wenn ihnen geholfen werden soll. Mit den Quellcode Schnipseln kann ich bspw. nix anfangen, da ich weder die Unit AudioSessionEvents habe, noch die Definition von AudioDevice oder SessionManager2. So ist das nur unvollständiges Stückwerk. |
AW: Das Handle ist ungültig
Zitat:
Ok macht ja nix muss mir dann selbst irgendwie weiter helfen. Danke gruss |
AW: Das Handle ist ungültig
Komplett lauffähiges Konsolenprogramm, alles in einer einzigen Unit.
Gibt bei mir aus:
Code:
DisplayName: @%SystemRoot%\System32\AudioSrv.Dll,-202
IconPath: @%SystemRoot%\System32\AudioSrv.Dll,-203
Delphi-Quellcode:
program AudioDevice;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Winapi.Windows, Winapi.ActiveX, Winapi.PropSys; const IID_IAudioSessionControl: TGUID = '{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}'; IID_IAudioSessionControl2: TGUID = '{bfb7ff88-7239-4fc9-8fa2-07c950be9c6d}'; IID_IAudioSessionManager: TGUID = '{BFA971F1-4D5E-40BB-935E-967039BFBEE4}'; IID_IAudioSessionManager2: TGUID = '{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}'; CLASS_IMMDeviceEnumerator: TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}'; IID_IMMDeviceEnumerator: TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}'; IID_IMMDevice: TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}'; IID_IMMDeviceCollection: TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}'; IID_IMMAudioEndpointVolume: TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}'; IID_IAudioMeterInformation: TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}'; IID_IAudioEndpointVolumeCallback: TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}'; IID_IMMNotificationClient: TGUID = '{7991EEC9-7E89-4D85-8390-6C703CEC60C0}'; DEVICE_STATE_ACTIVE = $00000001; DEVICE_STATE_UNPLUGGED = $00000002; DEVICE_STATE_NOTPRESENT = $00000004; DEVICE_STATEMASK_ALL = $00000007; type EDataFlow = TOleEnum; const eRender = $00000000; eCapture = $00000001; eAll = $00000002; EDataFlow_enum_count = $00000003; type ERole = TOleEnum; const eConsole = $00000000; eMultimedia = $00000001; eCommunications = $00000002; ERole_enum_count = $00000003; type IAudioSessionEvents = interface end; IAudioSessionControl = interface(IUnknown) ['{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}'] function GetState(out pRetVal: uint): HRESULT; stdcall; function GetDisplayName(out pRetVal: LPWSTR): HRESULT; stdcall; function SetDisplayName(Value: LPCWSTR; EventContext: pGuid): HRESULT; stdcall; function GetIconPath(out pRetVal: LPWSTR): HRESULT; stdcall; function SetIconPath(Value: LPCWSTR; EventContext: pGuid): HRESULT; stdcall; function GetGroupingParam(pRetVal: pGuid): HRESULT; stdcall; function SetGroupingParam(OverrideValue, EventContext: pGuid): HRESULT; stdcall; function RegisterAudioSessionNotification(const NewNotifications: IAudioSessionEvents) : HRESULT; stdcall; function UnregisterAudioSessionNotification(const NewNotifications: IAudioSessionEvents) : HRESULT; stdcall; end; IAudioSessionControl2 = interface(IAudioSessionControl) [IID_IAudioSessionControl2] function GetSessionIdentifier(out pRetVal: LPWSTR): HRESULT; stdcall; function GetSessionInstanceIdentifier(out pRetVal: LPWSTR): HRESULT; stdcall; function GetProcessId(out pRetVal: DWord): HRESULT; stdcall; // indicates whether the session is a system sounds session. function IsSystemSoundsSession(): HRESULT; stdcall; // S_OK = The session is a system sounds session. // S_FALSE = The session is not a system sounds session. function SetDuckingPreference(const optOut: Boolean): HRESULT; stdcall; // A BOOL variable that enables or disables system auto-ducking. end; IAudioSessionEnumerator = interface(IUnknown) ['{E2F5BB11-0570-40CA-ACDD-3AA01277DEE8}'] function GetCount(out SessionCount: Integer): HRESULT; stdcall; function GetSession(const SessionCount: Integer; out Session: IAudioSessionControl): HRESULT; stdcall; end; IAudioSessionNotification = interface end; IAudioVolumeDuckNotification = interface end; ISimpleAudioVolume = interface(IUnknown) ['{87CE5498-68D6-44E5-9215-6DA47EF883D8}'] function SetMasterVolume(fLevel: Single; EventContext: pGuid): HRESULT; stdcall; function GetMasterVolume(out fLevel: Single): HRESULT; stdcall; function SetMute(bMute: LongBool; EventContext: pGuid): HRESULT; stdcall; function GetMute(out bMute: LongBool): HRESULT; stdcall; end; IAudioSessionManager = interface(IUnknown) [IID_IAudioSessionManager] function GetAudioSessionControl(AudioSessionGuid: pGuid; StreamFlag: uint; out SessionControl: IAudioSessionControl) : HRESULT; stdcall; function GetSimpleAudioVolume(AudioSessionGuid: pGuid; StreamFlag: uint; out AudioVolume: ISimpleAudioVolume) : HRESULT; stdcall; end; IAudioSessionManager2 = interface(IAudioSessionManager) [IID_IAudioSessionManager2] function GetSessionEnumerator(out SessionEnum: IAudioSessionEnumerator): HRESULT; stdcall; function RegisterSessionNotification(SessionNotification: IAudioSessionNotification): HRESULT; stdcall; function UnregisterSessionNotification(SessionNotification: IAudioSessionNotification): HRESULT; stdcall; function RegisterDuckNotification(const sessionID: LPCWSTR; const duckNotification: IAudioVolumeDuckNotification) : HRESULT; stdcall; function UnregisterDuckNotification(const duckNotification: IAudioVolumeDuckNotification): HRESULT; stdcall; end; IAudioEndpointVolumeCallback = interface(IUnknown) [IID_IAudioEndpointVolumeCallback] end; IMMAudioEndpointVolume = interface(IUnknown) [IID_IMMAudioEndpointVolume] function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall; function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall; function GetChannelCount(out PInteger): Integer; stdcall; function SetMasterVolumeLevel(fLevelDB: Double; pguidEventContext: TGUID): Integer; stdcall; function SetMasterVolumeLevelScalar(fLevelDB: Double; pguidEventContext: TGUID): Integer; stdcall; function GetMasterVolumeLevel(out fLevelDB: Double): Integer; stdcall; function GetMasterVolumeLevelScaler(out fLevel: Double): Integer; stdcall; function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: Double; pguidEventContext: TGUID): Integer; stdcall; function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: Double; pguidEventContext: TGUID): Integer; stdcall; function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: Double): Integer; stdcall; function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: Double): Integer; stdcall; function SetMute(bMute: Boolean; pguidEventContext: TGUID): Integer; stdcall; function GetMute(out bMute: Boolean): Integer; stdcall; function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): Integer; stdcall; function VolumeStepUp(pguidEventContext: TGUID): Integer; stdcall; function VolumeStepDown(pguidEventContext: TGUID): Integer; stdcall; function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall; function GetVolumeRange(out pflVolumeMindB: Double; out pflVolumeMaxdB: Double; out pflVolumeIncrementdB: Double) : Integer; stdcall; end; IMMDevice = interface(IUnknown) [IID_IMMDevice] function Activate(const iid: TGUID; dwClsCtx: uint; pActivationParams: PPropVariant; out ppInterface: IUnknown) : HRESULT; stdcall; function OpenPropertyStore(stgmAccess: Integer; out ppProperties: IPropertyStore): HRESULT; stdcall; function GetId(ppstrId: PWChar): HRESULT; stdcall; function GetState(var pdwState: uint): HRESULT; stdcall; end; IMMDeviceCollection = interface(IUnknown) [IID_IMMDeviceCollection] function GetCount(var pcDevices: uint): HRESULT; stdcall; function Item(nDevice: uint; out ppDevice: IMMDevice): HRESULT; stdcall; end; IMMNotificationClient = interface(IUnknown) [IID_IMMNotificationClient] end; IMMDeviceEnumerator = interface(IUnknown) [IID_IMMDeviceEnumerator] function EnumAudioEndpoints(dataFlow: EDataFlow; dwStateMask: DWord; out ppDevices: IMMDeviceCollection): HRESULT; stdcall; function GetDefaultAudioEndpoint(dataFlow: EDataFlow; role: ERole; out ppEndpoint: IMMDevice): HRESULT; stdcall; function GetDevice(pwstrId: PWChar; out ppDevice: IMMDevice): HRESULT; stdcall; function RegisterEndpointNotificationCallback(var pClient: IMMNotificationClient): HRESULT; stdcall; function UnregisterEndpointNotificationCallback(var pClient: IMMNotificationClient): HRESULT; stdcall; end; procedure PrintDefaultSessionControlDisplayName; var DeviceEnumerator: IMMDeviceEnumerator; SessionManager: IAudioSessionManager; SessionManager2: IAudioSessionManager2; AudioDevice: IMMDevice; SessionControl2: IAudioSessionControl2; SessionEnumerator: IAudioSessionEnumerator; SessionControl: IAudioSessionControl; HR: HRESULT; SessionCount: Integer; pRetVal: PWideChar; begin SessionCount := 0; HR := CoInitializeEx(nil, 0); if Succeeded(HR) then begin HR := CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_ALL, IID_IMMDeviceEnumerator, DeviceEnumerator); if Succeeded(HR) then begin HR := DeviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, AudioDevice); if Succeeded(HR) then begin HR := AudioDevice.Activate(IID_IAudioSessionManager, CLSCTX_INPROC_SERVER, nil, IUnknown(SessionManager)); if Succeeded(HR) then begin if Supports(SessionManager, IID_IAudioSessionManager2, SessionManager2) then begin HR := SessionManager2.GetSessionEnumerator(SessionEnumerator); if Succeeded(HR) then begin HR := SessionEnumerator.GetSession(SessionCount, SessionControl); if Succeeded(HR) then begin if Supports(SessionControl, IID_IAudioSessionControl2, SessionControl2) then begin SessionControl2.GetDisplayName(pRetVal); Writeln('DisplayName: ', pRetVal); CoTaskMemFree(pRetVal); SessionControl2.GetIconPath(pRetVal); Writeln('IconPath: ', pRetVal); CoTaskMemFree(pRetVal); end; end; end; end; end; end; end; CoUninitialize; end; end; begin try PrintDefaultSessionControlDisplayName; Readln; except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); Readln; end; end; end. |
AW: Das Handle ist ungültig
Sieht gut aus..)
Muss das mal mit meiner Herangehensweise vergleichen. Bin auch schon was weiter wenn auch mit ach und krach muss noch einiges optimiert werden. Zum Beispiel scheint MS die SideBar zu kombinieren. Bei mir wird für jedes das Sound enthält ein Control erstellt. Danke. gruss |
AW: Das Handle ist ungültig
Nope habe deine Funktion testweise mal eingebaut da kommt nichts an.
Beides bleibt leer. ........... Dein Projekt ohne Änderung kompiliert D2010 Siehe das Ergebnis. Sollte eigentlich den Namen und den IconPfad meiner Anwendung anzeigen.Tut's aber nicht. Und wenn ich die Konsole vorher starte und anschließend ein Sound Programm stürzt das Konsolen teil ab. Hmmm.. vielleicht lege ich das Projekt erst mal zur Seite. Hier die Änderung damit es nicht mehr abstürzt. Aber funktionieren tut es trotzdem nicht. (Win7 Problem? Keine Ahnung)
Delphi-Quellcode:
gruss
procedure PrintDefaultSessionControlDisplayName;
var DeviceEnumerator: IMMDeviceEnumerator; SessionManager: IAudioSessionManager; SessionManager2: IAudioSessionManager2; AudioDevice: IMMDevice; SessionControl2: IAudioSessionControl2; SessionEnumerator: IAudioSessionEnumerator; SessionControl: IAudioSessionControl; HR: HRESULT; SessionCount: Integer; pRetVal: PWideChar; begin SessionCount := 0; HR := CoInitializeEx(nil, 0); if Succeeded(HR) then begin HR := CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_ALL, IID_IMMDeviceEnumerator, DeviceEnumerator); if Succeeded(HR) then begin HR := DeviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, AudioDevice); if Succeeded(HR) then begin HR := AudioDevice.Activate(IID_IAudioSessionManager, CLSCTX_INPROC_SERVER, nil, IUnknown(SessionManager)); if Succeeded(HR) then begin if Supports(SessionManager, IID_IAudioSessionManager2, SessionManager2) then begin HR := SessionManager2.GetSessionEnumerator(SessionEnumerator); if Succeeded(HR) then begin HR := SessionEnumerator.GetSession(SessionCount, SessionControl); if Succeeded(HR) then begin if Supports(SessionControl, IID_IAudioSessionControl2, SessionControl2) then begin SessionControl2.GetDisplayName(pRetVal); Writeln('DisplayName: ', pRetVal); CoTaskMemFree(pRetVal); SessionControl2.GetIconPath(pRetVal); Writeln('IconPath: ', pRetVal); CoTaskMemFree(pRetVal); end; SessionControl2 := nil; end; SessionControl := nil; end; SessionEnumerator := nil; end; SessionManager2 := nil; end; SessionManager := nil; end; end; DeviceEnumerator := nil; CoUninitialize; end; end; |
AW: Das Handle ist ungültig
Bei mir wird es auch korrekt angezeigt, aber unter Windows 10. Windows 7 habe ich leider nicht zur Verfügung zum Testen.
|
AW: Das Handle ist ungültig
Zitat:
Ich kann machen was ich will beide WideChars ergeben immer .. nothing. :) Ein
Delphi-Quellcode:
if Supports(SessionControl
Ist nicht unbedingt nötig denn wenn ich ein query auf SessionControl2 ausführe würde es wenn nicht unterstützt eh fehl schlagen. so..
Delphi-Quellcode:
HR := SessionControl.QueryInterface(IAudioSessionControl2, SessionControl2);
oder so
Delphi-Quellcode:
if Supports(SessionManager, IID_IAudioSessionManager2, SessionManager2) then
bleibt sich gleich. Mein Test bezieht sich auf das von mir korrigierte Obige Schnipsel. Alle Test's schlagen fehl. gruss |
AW: Das Handle ist ungültig
Zitat:
![]() Zitat:
GetSessionIdentifier gibt übrigens immer etwas zurück, auch unter Windows 7. |
AW: Das Handle ist ungültig
Zitat:
Ich liste alle Prozesse auf addiere diese zu einer liste und prüfe ob irgendeiner davon diese Bedingung erfüllt.
Delphi-Quellcode:
if State <> uint(TAudioSessionState.AudioSessionStateExpired) then
Zitat:
Wenn du das meinst ? Ja! Zitat:
Delphi-Quellcode:
(Ok war\ist eh leer von daher erst mal egal)
CoTaskMemFree(pDisplayName);
Zitat:
Es wird also geprüft ob es sich um eine echte Anwendung handelt, wenn ja wird nix zurück gegeben um zu verhindern das Developer den Mixer in dieser Art nachahmen können. Diese Funktion ist dann einfach Nutzlos. gruss |
AW: Das Handle ist ungültig
Mein Problem ist also..
Ich muss den DisplayNamen bzw.. den Pfad zum IconPath selbst vorher setzen. Macht irgendwo keine sinn. Es wären zwei funktionsaufrufe die letztendlich für die Katz sind wenn ich anschließend selbst noch das Icon bzw. den DisplayNamen selbst noch suchen muss. Das würde also ausreichen.
Delphi-Quellcode:
kann mir das dann schenken und muss anstelle dessen versuchen den Korrekten Namen zu analysieren.
FAudioSessionList[Index].DisplayName := pDisplayName;
if AudioSessionInfo(Index).DisplayName = '' then FAudioSessionList[Index].DisplayName := ExtractFileName (ChangeFileExt(GetBaseNameFromPID(PID), '')); CoTaskMemFree(pDisplayName);
Delphi-Quellcode:
GetBaseNameFromPID
Hmm.. was für ein schmarrn ;) gruss |
AW: Das Handle ist ungültig
Zitat:
Hier nochmal auf Deutsch: Zitat:
Was heißt das also? Es besagt, dass es für Programme wie Skype, Chrome, Internet Explorer, FireFox, WinAmp, VLC KEINE Pflicht ist, das Interface IAudioSessionControl zu implementieren bzw. die Methode SetDisplayName aufzurufen. Keine Ahnung, was du eigentlich bezwecken möchtest??? Wahrscheinlich setzt du einfach voraus, dass wir alle deine Beiträge lesen und wir daher genau wissen, woran du arbeitest und den Rest können wir uns gefälligst selber zusammenreimen. Wäre ja auch noch schöner, ein vollständiges Gegeben, Gesucht und zumindest einen Lösungsansatz zu verlangen. :o Möchtest eine der folgenden Informationen?
Code:
- - - - - - - - - - - - - - - - - -
SessionIndex: 0 SessionIdentifier: {0.0.0.00000000}.{18e53891-8712-4c0d-9aab-e23e4b813b96}|#%b{A9EF3FD9-4240-455E-A4D5-F2B3301887B2} SessionInstanceIdentifier: {0.0.0.00000000}.{18e53891-8712-4c0d-9aab-e23e4b813b96}|#%b{A9EF3FD9-4240-455E-A4D5-F2B3301887B2}|12%b# DisplayName: @%SystemRoot%\System32\AudioSrv.Dll,-202 IconPath: @%SystemRoot%\System32\AudioSrv.Dll,-203 Process ID: 0 - - - - - - - - - - - - - - - - - - SessionIndex: 1 SessionIdentifier: {0.0.0.00000000}.{18e53891-8712-4c0d-9aab-e23e4b813b96}|\Device\HarddiskVolume4\Program Files (x86)\Google\Chrome\Application\chrome.exe%b{00000000-0000-0000-0000-000000000000} SessionInstanceIdentifier: {0.0.0.00000000}.{18e53891-8712-4c0d-9aab-e23e4b813b96}|\Device\HarddiskVolume4\Program Files (x86)\Google\Chrome\Application\chrome.exe%b{00000000-0000-0000-0000-000000000000}|12%b13524 DisplayName: IconPath: Process ID: 13524 ProcessName: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe - - - - - - - - - - - - - - - - - - SessionIndex: 2 SessionIdentifier: {0.0.0.00000000}.{18e53891-8712-4c0d-9aab-e23e4b813b96}|\Device\HarddiskVolume4\Program Files (x86)\Skype\Phone\Skype.exe%b{00000000-0000-0000-0000-000000000000} SessionInstanceIdentifier: {0.0.0.00000000}.{18e53891-8712-4c0d-9aab-e23e4b813b96}|\Device\HarddiskVolume4\Program Files (x86)\Skype\Phone\Skype.exe%b{00000000-0000-0000-0000-000000000000}|12%b184 DisplayName: IconPath: Process ID: 184 ProcessName: C:\Program Files (x86)\Skype\Phone\Skype.exe |
AW: Das Handle ist ungültig
Zitat:
Zitat:
Also muss ich hier den DisplayNamen und den Pfad zum Icon selber setzen.. Ist das jetzt deutlich genug? Zitat:
Du musst mich auch nicht auf diese Art hier belehren das mag ich gar nicht!. :evil: Zudem bringen mir deine Infos nichts denn die Strings bleiben wie zuvor leer. Auch wenn bsp. Winamp Zitat:
Zum IExplorer habe ich ja schon einen Shot geschickt. (Es geht also) So nun mit all deinen klugen Sprüchen (Belehrungen) wenn MS es kann warum funktioniert es dann nicht bei mir? Ach vergiss es einfach.. Ich finde eine Lösung dessen kannst du sicher sein! gruss |
AW: Das Handle ist ungültig
Zitat:
|
AW: Das Handle ist ungültig
Zitat:
Was ich möchte.. das TAudioVolume auf einen Kompletten Mixer erweitern so wie er sichtbar wird wie wenn man im Tray auf das Lautsprecher Symbol klickt. EDIT: Schlage mich jetzt mit der Änderung rum. Durch die Änderung auf GetProcessImageFileNameW habe ich nun Probleme den korrekten Pfad zu Anwendung zu finden um das Icon zu setzen. Muss diesen Pfad Zitat:
Und so geht es immer weiter.. ;)
Delphi-Quellcode:
FullPath ist leer.. :)
a := MAX_PATH;
GetVolumePathNamesForVolumeNameW(PWideChar(FAudioSessionList[Index].IconPath), @FullPath, MAX_PATH, a); SetSysItemIcon(FullPath); gruss |
AW: Das Handle ist ungültig
Zitat:
Du hast den vollständigen Processpfad/-dateinamen, du hast das Process Handle, du hast die Process ID...woran scheitert es jetzt genau? Hier noch ein Schups in die richtige Richtung, weil heute Donnerstag ist:
Delphi-Quellcode:
procedure ExtractIcons(const FileName: string);
var IconCount: Cardinal; I: Integer; IconHandle: HICON; begin IconCount := ExtractIcon(HInstance, PChar(FileName), UINT(-1)); if IconCount <> 0 then begin for I := 0 to IconCount - 1 do begin IconHandle := ExtractIcon(HInstance, PChar(FileName), I); if IconHandle <> 0 then begin // mach irgendwas mit dem Icon Handle // . . . // am Ende freigeben DestroyIcon(IconHandle); end; end; end; end; |
AW: Das Handle ist ungültig
Zitat:
Delphi-Quellcode:
SessionControl2.GetProcessId(ProcessId);
Writeln('Process ID: ', ProcessId); ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessId); if ProcessHandle <> 0 then begin if GetModuleFileNameEx(ProcessHandle, 0, ProcessName, MAX_PATH) <> 0 then begin Writeln('ProcessName: ', ProcessName); end; CloseHandle(ProcessHandle); end; |
AW: Das Handle ist ungültig
Zitat:
Nicht nur GetModuleBaseName (gibt den ExeNamen ohne Pfad zurück) verursacht diesen Fehler auch GetModuleFileNameEx (ExeNamen inklusive Pfad) Hier gibt es den Fehler das mein Handle ungültig ist. Deshalb haben wir es doch geändert. Zitat:
Delphi-Quellcode:
gruss
procedure TAudioVolume.SetSysItemIcon(wsItems: PWideChar);
var fi: TSHFileInfo; begin ZeroMemory(@fi, sizeof(TSHFileInfo)); if SHGetFileInfo(wsItems, 0, fi, sizeof(TSHFileInfo), SHGFI_DISPLAYNAME Or SHGFI_SYSICONINDEX or SHGFI_LARGEICON or SHGFI_ICON) <> 0 then Icon := fi.HICON; end; |
AW: Das Handle ist ungültig
Zitat:
Delphi-Quellcode:
FAudioSessionList[Index].DisplayName := GetBaseNameFromPID(PID);
Woher kommt die Variable PID? Oder um die Frage vielleicht klarer zu stellen: Wie ermittelst du den Wert von PID? Wenn die Process ID gültig ist - also wie von mir gezeigt per einzelner SessionControl-Instanz geholt - dann muss OpenProcess ein gültiges Handle liefern. Ansonsten machst du was falsch. Laufen die Programme vielleicht als Administrator ("Als Administrator ausführen")? Dann kann OpenProcess so nicht funktionieren. Vergleiche mit Konsolenausgabe in Beitrag #24: ![]() |
AW: Das Handle ist ungültig
Zitat:
Zitat:
Delphi-Quellcode:
HR := SessionControl2.GetProcessID(PID);
if Succeeded(HR) then begin FAudioSessionList[Index].ProcessID := intToStr(PID); HR := SessionControl2.GetState(State); if Succeeded(HR) then begin if PID = ProcId then begin if State <> uint(TAudioSessionState.AudioSessionStateExpired) then begin Zitat:
Sonst würde ja alles funktionieren. Anwendung..
Delphi-Quellcode:
AudioVolume[i].GetSessionCount(AudioVolume1.Device);
if AudioVolume1.AudioSessionInfo(i).PID <> 0 then
Delphi-Quellcode:
Ok hier GetSessionCount muss ich noch was tun es dauert einfach zu lange für jedes control diese Funktion zu durchlaufen.
function TAudioVolume.GetSessionCount(AudioDevice: IMMDevice): integer;
var SessionControl2: IAudioSessionControl2; SessionControl: IAudioSessionControl; pEnumerator: IAudioSessionEnumerator; SCount: Integer; PID, ProcId: DWORD; State: uint; HR: HResult; i, j: integer; ProcList: TStringList; begin ProcList := TStringList.Create; SCount := 0; GetProzessList(ProcList); if Assigned(SessionManager2) then begin HR := AudioDevice.Activate(IID_IAudioSessionManager2, CLSCTX_ALL, nil, IUnknown(SessionManager2) ); if Succeeded(HR) then begin // get SessionQuery HR := SessionManager2.GetSessionEnumerator(pEnumerator); if Succeeded(HR) then begin HR := pEnumerator.GetCount(FSessionCount); if Succeeded(HR) then Setlength(FAudioSessionList, FSessionCount + 1); if Succeeded(HR) then begin for i := 0 to FSessionCount - 1 do begin HR := pEnumerator.GetSession(i, SessionControl); if Succeeded(HR) then begin HR := SessionControl.QueryInterface(IAudioSessionControl2, SessionControl2); if Succeeded(HR) then begin HR := SessionControl2.GetProcessID(PID); if Succeeded(HR) then begin HR := SessionControl2.GetState(State); if Succeeded(HR) then begin for j := 0 to ProcList.Count - 1 do begin ProcId := GetProcessIdFromModuleName(pWideChar(ProcList[j])); if (PID = ProcId) and (PID <> GetCurrentProcessId) then begin if State <> uint(TAudioSessionState.AudioSessionStateExpired) then begin FAudioSessionList[i].ActiveSession := IntToStr(i); FAudioSessionList[i].PID := PID; inc(SCount, i); end; end; end; end; end; end; SessionControl2 := nil; end; SessionControl := nil; end; end; end; pEnumerator := nil; end; end; ProcList.free; Result := SCount; end; gruss |
AW: Das Handle ist ungültig
Ich gab Dir
![]() |
AW: Das Handle ist ungültig
Zitat:
Ich sagte doch schon das habe ich alles schon durch deshalb habe ich doch den Thread hier erstellt. Ich sammle auch nicht die Funktionen andere Leute sondern erarbeite sie selbst. Es hat bei meiner Funktion
Delphi-Quellcode:
gekracht wegen ungültigen Handle.
function TAudioVolume.GetPathFromPID(const PID: DWORD): string;
var hProcess: THandle; path: array [0 .. MAX_PATH - 1] of WChar; begin hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID); if hProcess <> 0 then try if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) = 0 then RaiseLastOSError; Result := path; finally CloseHandle(hProcess) end else RaiseLastOSError; end; Bei der Sidebar und dem IExplorer bei normalen Anwendungen seltsamer weise nicht. gruss |
AW: Das Handle ist ungültig
Ich werfe einfach mal was in den Raum obwohl ich mir nicht 100%ig sicher bin ob das relevant ist.
Kann es vllt. ein 32-Bit <-> 64-Bit Problem sein, dass du in deiner 32-Bit Anwendung vllt. keine 64-Bit Prozesse öffnen kannst/darfst? Sowas kam mir nur in den Kopf.. kann aber durchaus sein, dass ich Unsinn rede. |
AW: Das Handle ist ungültig
Zitat:
Nur dafür fehlen mir die Möglichkeiten. Auf der anderen Seite dürfte dann gar nichts gehen denn ich denke das die API ja letztendlich auch auf die 64Bit Prozesse der Soundkarten Treiber zugreift oder? Oder aber die werden umgelenkt. Dann müsste es aber funktionieren. gruss |
AW: Das Handle ist ungültig
Zitat:
![]() ![]() ![]() ![]() Siehe hier: ![]() Edit: Habe grade unter Win10 nochmal geschaut (mein Post von damals ist ja schon ein wenig in die Jahre gekommen) und das Verhalten hat sich scheinbar geändert. Mitlerweile funktioniert GetModuleFilenameEx wohl auch bei 64-Bit Prozessen. |
AW: Das Handle ist ungültig
Danke dir werde mir das mal anschauen.
EDIT: Also kein Problem scheint zu funktionieren. Auch das Icon bekomme ich nun. Muss das jetzt erst mal zuweisen um das Ergebnis sehen zu können. gruss |
AW: Das Handle ist ungültig
Delphi-Quellcode:
Warum eigentlich der Vergleich von PID mit der ProcID, die du über die gefüllte ProcList holst? Wozu dient das?
for j := 0 to ProcList.Count - 1 do
begin ProcId := GetProcessIdFromModuleName(pWideChar(ProcList[j])); if (PID = ProcId) and (PID <> GetCurrentProcessId) then begin if State <> uint(TAudioSessionState.AudioSessionStateExpired) then begin FAudioSessionList[i].ActiveSession := IntToStr(i); FAudioSessionList[i].PID := PID; inc(SCount, i); end; end; end; Die PID, die du mit SessionControl2.GetProcessID(PID); ermittelst, gibt dir doch eine gültige Process ID einer Audiosession? Der ieexplore lässt sich ohne große Verrenkungen per OpenProcess ermitteln:
Code:
ProcessName wird über OpenProcess() und GetModuleFileNameEx() geholt.
SessionIndex: 2
SessionIdentifier: {0.0.0.00000000}.{18e53891-8712-4c0d-9aab-e23e4b813b96}|#%b{63C9CE85-D9FF-4AE9-A105-C25B9A69E0C8} SessionInstanceIdentifier: {0.0.0.00000000}.{18e53891-8712-4c0d-9aab-e23e4b813b96}|#%b{63C9CE85-D9FF-4AE9-A105-C25B9A69E0C8}|12%b# DisplayName: IconPath: Process ID: 5444 ProcessName: C:\Program Files (x86)\Internet Explorer\iexplore.exe |
AW: Das Handle ist ungültig
Du solltest deiner
Delphi-Quellcode:
Methode in der ersten Zeile übrigens ein
TAudioVolume.GetPathFromPID
Delphi-Quellcode:
gönnen. Sicher ist sicher!
Result := '';
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:57 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