実行中のプログラムのリストを取得して、Windowsタスクマネージャーの[アプリケーション]タブ([プロセス]タブではない)に表示し、HDD上の場所を取得したいですか?
Delphiで実行する必要があります。誰でも助けることができますか?
2 に答える
私の知る限り、タスクマネージャーの[アプリケーション]タブは、他のウィンドウが所有しておらず、親がなく、ツールウィンドウではないトップレベルのウィンドウのリストです。私のプロセス情報には、そのような特性を持つウィンドウのリストを返すAppInfo.pasというユニットがあり、そのリストはタスクマネージャーに表示されるものと一致します。EnumWindowsAPI関数のコールバック関数として記述されたコードの主要部分は次のとおりです。
{$IFDEF DELPHI2007UP}
class function TAppWindowCollection.EnumWinProc(wHandle: HWND; lparam: integer): Bool;
{$ELSE}
function EnumWinProc(wHandle: HWND; lparam: integer): Bool; stdcall;
{$ENDIF}
Const
MAX_TEXT = MAX_PATH;
var
WindowItem : TWindowItem;
strText,strClass : array [0..MAX_TEXT] of char;
IsAppMainWin : Boolean;
begin
//Check if the window is a visible application main window.
IsAppMainWin := IsWindowVisible(wHandle) AND //Visible
(GetWindow(wHandle,GW_OWNER) = 0) AND //Not owned by other windows
(GetParent(wHandle) = 0) AND //Does not have any parent
(GetWindowLong(wHandle,GWL_EXSTYLE) AND WS_EX_TOOLWINDOW = 0); //Not a tool window
if IsAppMainWin then
begin
WindowItem := TAppWindowCollection(lparam).Add;
GetWindowText(wHandle,strText,MAX_TEXT);
GetClassName(wHandle,strClass,MAX_TEXT);
WindowItem.FCaption := strText;
WindowItem.FHandle := wHandle;
WindowItem.FWindowClass := strClass;
GetWindowThreadProcessId(wHandle,WindowItem.FProcessID);
end;
Result := True;
end;
完全なソースコードについては、AppInfo.pasを参照してください。
そしてHDD上でそれらの場所を取得します
これらは単なるウィンドウです。各項目に対応するEXEファイルのパスを取得したい場合は、まずGetWindowThreadProcessID API関数を使用して、このウィンドウを所有しているプロセスを見つける必要があります。それは私が上記のコードでしたことです。プロセスIDを取得すると、そこからプロセスハンドルを取得し、そのモジュールを列挙できます。最初のモジュールはメインのEXEファイルです。AppInfo.pasと同じパッケージに含まれているTProcessInfoコンポーネントに実装しました。
これが完全なスタンドアロンソリューションです(壊れたリンクはもうありません)
program ApplicationList;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Winapi.Windows,
Winapi.PsAPI;
function GetPathFromPID( const PID : cardinal ) : string;
var
hProcess : THandle;
path : array [0 .. MAX_PATH - 1] of char;
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;
function EnumWinProc( wHandle : hWnd; lparam : integer ) : Bool; stdcall;
Const
MAX_TEXT = MAX_PATH;
var
strText, strClass : array [0 .. MAX_TEXT] of char;
strPath : string;
IsAppMainWin : Boolean;
ProcId : cardinal;
begin
// Check if the window is a visible application main window.
IsAppMainWin := IsWindowVisible( wHandle ) AND // Visible
( GetWindow( wHandle, GW_OWNER ) = 0 ) AND // Not owned by other windows
( GetParent( wHandle ) = 0 ) AND // Does not have any parent
( GetWindowLong( wHandle, GWL_EXSTYLE ) AND WS_EX_TOOLWINDOW = 0 ); // Not a tool window
if IsAppMainWin
then
begin
GetWindowText( wHandle, strText, MAX_TEXT );
GetClassName( wHandle, strClass, MAX_TEXT );
GetWindowThreadProcessID( wHandle, ProcId );
try
strPath := GetPathFromPID( ProcId );
except
strPath := '???';
end;
WriteLn( ProcId, ' - ', strClass, ' - ', strText, ' - ', strPath );
end;
Result := True;
end;
procedure DoEnumWindows;
var
FirstWnd : cardinal;
begin
EnumWindows( @EnumWinProc, cardinal( @FirstWnd ) );
end;
begin
try
DoEnumWindows;
except
on E : Exception do
WriteLn( E.ClassName, ': ', E.Message );
end;
ReadLn;
end.