Delphi-PRAXiS
Seite 4 von 10   « Erste     234 56     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Das Handle ist ungültig (https://www.delphipraxis.net/196216-das-handle-ist-ungueltig.html)

TiGü 3. Mai 2018 10:17

AW: Das Handle ist ungültig
 
Zitat:

Zitat von EWeiss (Beitrag 1401164)
Das hatten wir schon Seiten vorher... aber trotzdem Danke.
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.

Gehen wir nochmal ganz doll zurück zum ersten Beitrag:

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:
https://www.delphipraxis.net/1401141-post24.html

EWeiss 3. Mai 2018 10:27

AW: Das Handle ist ungültig
 
Zitat:

Laufen die Programme vielleicht als Administrator ("Als Administrator ausführen")? Dann kann OpenProcess so nicht funktionieren.
IExplorer und SideBar? denke schon.

Zitat:

Woher kommt die Variable PID? Oder um die Frage vielleicht klarer zu stellen: Wie ermittelst du den Wert von PID?
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:

Ansonsten machst du was falsch.
möglich ;)
Sonst würde ja alles funktionieren.

Anwendung..
Delphi-Quellcode:
    AudioVolume[i].GetSessionCount(AudioVolume1.Device);
    if AudioVolume1.AudioSessionInfo(i).PID <> 0 then
Delphi-Quellcode:
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;
Ok hier GetSessionCount muss ich noch was tun es dauert einfach zu lange für jedes control diese Funktion zu durchlaufen.

gruss

KodeZwerg 3. Mai 2018 10:41

AW: Das Handle ist ungültig
 
Ich gab Dir hier eine Funktion, wenn Du die mit Deiner ermittelten PID aufrufst, was kommt da raus, das was bei Dir auch rauskommen sollte?

EWeiss 3. Mai 2018 10:47

AW: Das Handle ist ungültig
 
Zitat:

Zitat von KodeZwerg (Beitrag 1401181)
Ich gab Dir hier eine Funktion, wenn Du die mit Deiner ermittelten PID aufrufst, was kommt da raus, das was bei Dir auch rauskommen sollte?

Ach mano ...
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:
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;
gekracht wegen ungültigen Handle.
Bei der Sidebar und dem IExplorer bei normalen Anwendungen seltsamer weise nicht.

gruss

Neutral General 3. Mai 2018 11:46

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.

EWeiss 3. Mai 2018 11:50

AW: Das Handle ist ungültig
 
Zitat:

Zitat von Neutral General (Beitrag 1401190)
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.

Wäre möglich aber um das genau feststellen zu können müsste man das Projekt nach 64Bit Portieren.
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

Zacherl 3. Mai 2018 11:58

AW: Das Handle ist ungültig
 
Zitat:

Zitat von Neutral General (Beitrag 1401190)
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?

MSDN-Library durchsuchenOpenProcess ist unproblematisch. Es gibt aber tatsächlich einige APIs, welche da Probleme bereiten. Alles was intern MSDN-Library durchsuchenZwReadVirtualMemory bzw. MSDN-Library durchsuchenReadProcessMemory verwendet, sind dafür beispielsweise Kandidaten. Hierzu zählt auch die verwendete MSDN-Library durchsuchenGetModuleFilenameEx API.

Siehe hier:
https://www.delphipraxis.net/160046-...ermitteln.html (Konvertierung vom NT-Pfad zu standard DOS-Pfad kann man sich hier auch anschauen)

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.

EWeiss 3. Mai 2018 12:04

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

TiGü 3. Mai 2018 12:56

AW: Das Handle ist ungültig
 
Delphi-Quellcode:
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;
Warum eigentlich der Vergleich von PID mit der ProcID, die du über die gefüllte ProcList holst? Wozu dient das?
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:
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
ProcessName wird über OpenProcess() und GetModuleFileNameEx() geholt.

TiGü 3. Mai 2018 13:01

AW: Das Handle ist ungültig
 
Du solltest deiner
Delphi-Quellcode:
TAudioVolume.GetPathFromPID
Methode in der ersten Zeile übrigens ein
Delphi-Quellcode:
Result := '';
gönnen. Sicher ist sicher!


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:02 Uhr.
Seite 4 von 10   « Erste     234 56     Letzte »    

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