Q&A

  • CreateToolhelp32Snapshot을 Windows NT에서
CreateToolhelp32Snapshot 함수를 써서

현재 실행중인 프로세스의 실행파일명을 구하고자 하는데

Windows NT에서 실행하면

함수의 실행 결과를 전혀 얻을수가 없네요.

XP나 2000에서는 제대로 구해지는데 NT에서만 되질 않네요.

누구 아시는분 계시면 가르쳐 주시면 고맙겠습니다.

<!--CodeS-->
procedure EnumProcess(Strings: TStrings);
var
  Snapshot: THandle;
  ProcessEntry: TProcessEntry32;
  NextProcess: BOOL;
begin
  Snapshot := CreateToolhelp32Snapshot( TH32CS_SNAPALL, GetCurrentProcessID );
  ProcessEntry.dwSize := SizeOf( TProcessEntry32 );
  NextProcess := Process32First( Snapshot, ProcessEntry );
  while NextProcess do
   begin
     Strings.Add( ProcessEntry.szExeFile + ' PID:' + IntToStr(ProcessEntry.th32ProcessID));
     NextProcess := Process32Next( Snapshot, ProcessEntry );
   end;
  CloseHandle( Snapshot );
end;
<!--CodeE-->
2  COMMENTS
  • Profile
    구창민 2007.10.20 02:45
    안녕하세요..

    워..아직도 NT를 사용하는 곳이 있군요..

    오래전 사이트를 돌아다니며 열심히 코딩했던 기억이 나서 찾아보니 있네요..

    9x계열은 TlHelp32 를 사용했고, NT 계열은 PsApi 를 사용한 코드입니다.

    시스템이 무엇인지를 조사해서 거기에 맞게 코딩했었습니다..

    보시고, 참고하셔서 즐거운 프로그래밍 하세요~~~



    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, PsApi, TlHelp32;

    type
      TForm1 = class(TForm)
        Button1: TButton;
        lbProcesses: TListBox;
        lbTasksList: TListBox;
        procedure Button1Click(Sender: TObject);
        procedure lbProcessesDblClick(Sender: TObject);
        procedure lbTasksListDblClick(Sender: TObject);
        procedure FormShow(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        function RunningProcessesList(const List: TStrings; FullPath: Boolean): Boolean;
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.DFM}


    function GetWindowsVersion: String;
    begin
      Result := '';
      case Win32Platform of
        VER_PLATFORM_WIN32_WINDOWS:
          case Win32MinorVersion of
            0:
              if Trim(Win32CSDVersion) = 'B' then
                Result := 'Win95OSR2'
              else
                Result := 'Win95';
            10:
              if Trim(Win32CSDVersion) = 'A' then
                Result := 'Win98SE'
              else
                Result := 'Win98';
            90:
              Result := 'WinME';
          end;
        VER_PLATFORM_WIN32_NT:
          case Win32MajorVersion of
            3:
              Result := 'WinNT3';
            4:
              Result := 'WinNT4';
            5:
              Result := 'Win2000';
          end;
      end;
    end;
    //------------------------------------------------------------------------------



    function TForm1.RunningProcessesList(const List: TStrings; FullPath: Boolean): B
    oolean;

      procedure StrResetLength(var S: AnsiString);
      begin
        SetLength(S, StrLen(PChar(S)));
      end;

      function ProcessFileName(PID: DWORD): string;
      var
        Handle: THandle;
      begin
        Result := '';
        Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
        if Handle <> 0 then
        try
          SetLength(Result, MAX_PATH);
          if FullPath then
          begin
            if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
              StrResetLength(Result)
            else
              Result := '';
          end
          else
          begin
            if GetModuleBaseNameA(Handle, 0, PChar(Result), MAX_PATH) > 0 then
              StrResetLength(Result)
            else
              Result := '';
          end;
        finally
          CloseHandle(Handle);
        end;
      end;

      function BuildListTH: Boolean;
      var
        SnapProcHandle: THandle;
        ProcEntry: TProcessEntry32;
        NextProc: Boolean;
        FileName: string;
      begin
        SnapProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        Result := (SnapProcHandle <> INVALID_HANDLE_VALUE);
        if Result then
        try
          ProcEntry.dwSize := SizeOf(ProcEntry);
          NextProc := Process32First(SnapProcHandle, ProcEntry);
          while NextProc do
          begin
            if ProcEntry.th32ProcessID = 0 then
            begin
              // PID 0 is always the "System Idle Process" but this name cannot be
              // retrieved from the system and has to be fabricated.
              FileName := 'System Idle Process';
            end
            else
            begin
              if GetWindowsVersion = 'Win2000' then
              begin
                FileName := ProcessFileName(ProcEntry.th32ProcessID);
                if FileName = '' then FileName := ProcEntry.szExeFile;
              end
              else
              begin
                FileName := ProcEntry.szExeFile;
                if not FullPath then FileName := ExtractFileName(FileName);
              end;
            end;
            List.AddObject(FileName, Pointer(ProcEntry.th32ProcessID));
            NextProc := Process32Next(SnapProcHandle, ProcEntry);
          end;
        finally
          CloseHandle(SnapProcHandle);
        end;
      end;

      function BuildListPS: Boolean;
      var
        PIDs: array [0..1024] of DWORD;
        Needed: DWORD;
        I: Integer;
        FileName: string;
      begin
        Result := EnumProcesses(@PIDs, SizeOf(PIDs), Needed);
        if Result then
        begin
          for I := 0 to (Needed div SizeOf(DWORD)) - 1 do
          begin
            case PIDs[I] of
              0:
                FileName := 'System Idle Process';
              2:
                if GetWindowsVersion = 'WinNT4' then
                  FileName := 'System Process'
                else
                  FileName := ProcessFileName(PIDs[I]);
              8:
                if GetWindowsVersion = 'Win2000' then
                  FileName := 'System Process'
                else
                  FileName := ProcessFileName(PIDs[I]);
              else
              FileName := ProcessFileName(PIDs[I]);
            end;
            if FileName <> '' then List.AddObject(FileName, Pointer(PIDs[I]));
          end;
        end;
      end;

    begin
      if (GetWindowsVersion = 'WinNT3') or (GetWindowsVersion = 'WinNT4') or
        (GetWindowsVersion = 'Win2000') then
        Result := BuildListPS
      else
        Result := BuildListTH;
    end;
    //------------------------------------------------------------------------------



    // http://msdn.microsoft.com/library/periodic/period97/win321197.htm 참고
    function GetTasksList(const List: TStrings): Boolean;

      function EnumWindowsProc(Wnd: HWND; List: TStrings): Boolean; stdcall;
      var
        ParentWnd: HWND;
        ExStyle: DWORD;
        Caption: array [0..255] of Char;
      begin
        if IsWindowVisible(Wnd) then
        begin
          ParentWnd := GetWindowLong(Wnd, GWL_HWNDPARENT);
          ExStyle := GetWindowLong(Wnd, GWL_EXSTYLE);
          if ((ParentWnd = 0) or (ParentWnd = GetDesktopWindow)) and
            ((ExStyle and WS_EX_TOOLWINDOW = 0) or (ExStyle and WS_EX_APPWINDOW <> 0)) and
            (GetWindowText(Wnd, Caption, SizeOf(Caption)) > 0) then
              List.AddObject(Caption, Pointer(Wnd));
        end;
        Result := True;
      end;

    begin
      Result := EnumWindows(@EnumWindowsProc, Integer(List));
    end;
    //------------------------------------------------------------------------------




    procedure TForm1.Button1Click(Sender: TObject);
    var
      i, max_width : integer;
    begin
      lbProcesses.Items.BeginUpdate;
      try
        lbProcesses.Items.Clear;
        RunningProcessesList(lbProcesses.Items, False);
      finally
        lbProcesses.Items.EndUpdate;
      end;

      lbTasksList.Items.BeginUpdate;
      try
        lbTasksList.Items.Clear;
        GetTasksList(lbTasksList.Items);
      finally
        lbTasksList.Items.EndUpdate;
      end;

      // 두 리스트 박스의 수평스크롤바 를 강제로 생성
      max_width := 0;
      for i := 0 to lbProcesses.Items.Count -1 do
      begin
        if (max_width < lbProcesses.Canvas.TextWidth(lbProcesses.items.strings[i]))
        then max_width := lbProcesses.canvas.TextWidth(lbProcesses.items.strings[i]);
      end;
      SendMessage(lbProcesses.Handle, LB_SETHORIZONTALEXTENT, max_width + 200, 0);


      max_width := 0;
      for i := 0 to lbTasksList.Items.Count -1 do
      begin
        if (max_width < lbTasksList.Canvas.TextWidth(lbTasksList.items.strings[i]))
        then max_width := lbTasksList.canvas.TextWidth(lbTasksList.items.strings[i]);
      end;
      SendMessage(lbTasksList.Handle, LB_SETHORIZONTALEXTENT, max_width + 200, 0);
    end;
    //------------------------------------------------------------------------------



    //Running Process Kill
    procedure TForm1.lbProcessesDblClick(Sender: TObject);
    var
      ProcessHandle : THandle;
    begin
      ProcessHandle := OpenProcess(PROCESS_TERMINATE, TRUE,
                        HWND(lbProcesses.Items.Objects[lbProcesses.ItemIndex]));
      TerminateProcess(ProcessHandle,0);
      CloseHandle(ProcessHandle);
    end;
    //------------------------------------------------------------------------------



    //TaskList Process Kill
    procedure TForm1.lbTasksListDblClick(Sender: TObject);
    begin
      PostMessage(HWND(lbTasksList.Items.Objects[lbTasksList.ItemIndex]), WM_Close,
    0, 0);
    end;
    //------------------------------------------------------------------------------



    procedure TForm1.FormShow(Sender: TObject);
    begin
      Button1.Click;
    end;
    //------------------------------------------------------------------------------



    end.



  • Profile
    강대근 2007.10.20 02:56
    감사합니다..
    • 초보자
    • 2007.10.21 01:50
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 착한천사
      2007.10.21 18:59
      sName[0] := 'AB'; sName[1] := 'ZY'; 입니다. sName[0][1] ==> 'A' sName[1][2] ==> 'Y' 쉽...
    • 초보자
      2007.10.22 00:22
      아.. 제 질문이 좀 부족했나보네요.. 제가 원하는것은 배열의 갯수가 많아서 한번에 세팅하고 싶은경우 입...
    • 착한천사
      2007.10.25 19:59
      변수에 일괄세팅하는것은 SET를 제외하고, pascal에서 안되는것으로 알고 있습니다. 그러나, 상수에게는 ...
    • 강대근
    • 2007.10.20 00:22
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 구창민
      2007.10.20 02:45
      안녕하세요.. 워..아직도 NT를 사용하는 곳이 있군요.. 오래전 사이트를 돌아다니며 열심히 코딩했...
    • 강대근
      2007.10.20 02:56
      감사합니다..
    • 문혜윤
    • 2007.10.18 03:19
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 찬우아빠
      2007.10.19 19:16
      아무도 답변을 안달아주시니 안따까운 마음에 제가 힌트라도 될까 싶어 적습니다.... 델파이나 디비 문...
    • 왕초보
      2007.10.19 23:13
      이 오류는 현재 커넥션되어있는 디비에서 자기를 리스토어하려고 한다는 오류인것 같은데요 아래와 같...
    • 미트몰
      2007.10.26 19:02
      답변감사합니다. 답변해주신 것처럼 프로그램 문제는 아니었고 메인메뉴 프로그램에서 ADO로 UserDB에 C...
    • 구창민
    • 2007.10.17 23:00
    • 6 COMMENTS
    • /
    • 0 LIKES
    • 착한천사
      2007.10.25 20:20
      쵸코파이는 맛있는거.. 델파이는 골때리는거.. 엄청난 차이가 있죠.. ps. 이건 자게로 이사하는것이 ...
    • 구창민
      2007.10.26 01:32
      이사하기 싫다면 어쩌 실 겁니까?
    • 손귀선
      2007.10.20 03:32
      아무런 관계가 없는 듯 한데... 아마도 국산 찌짐 이나, 전 과 관계가 있는 듯.... ^^; 델 찌짐, 델 ...
    • 구창민
      2007.10.26 01:36
      훌륭한 답변 감사드립니다~ 저도 귀선님 처럼 훌륭한 개발자가 되어서 좋은 답변 하겠습니다~ 좋은 ...
    • 찬우아빠
      2007.10.17 23:07
      //============================================// 초코파이(Chocopie)는 두 개의 원형 비스켓을 메쉬...
    • 구창민
      2007.10.26 01:36
      답변 감사합니다~ ㅎㅎ
    • 모민현
    • 2007.10.17 20:41
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 찬우아빠
      2007.10.17 21:13
      구현하기 나름일텐데요.. 단지 버튼크릭으로 구현하실꺼라면 트리뷰는 Align 속성 aLeft로 panel은 Alin...
    • 모민현
    • 2007.10.17 19:19
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 찬우아빠
      2007.10.17 19:26
      implementation uses unit2; {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); begin ...
    • 모민현
      2007.10.17 19:43
      uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  ...
    • 찬우아빠
      2007.10.17 19:49
      거기다 Panel1을 넣으시면 안되구요.. standard 탭에 있는 패널을 선택하셔서 form1에 올려놓으시면 ...
    • 모민현
      2007.10.17 19:53
      잘 되네요^^
    • 최용일
      2007.10.17 11:31
      안녕하세요. 최용일입니다. 제 생각에는 저장은 되는데 저장된 파일이 어디 있는지 잘 모르시는 것 같습...
    • 야단났네~*
      2007.10.17 20:35
      감사합니다. 지적하신 그 문제였습니다. 예전에도 동일한 문제로 헤맨적이 있었는데...
    • 박철우
    • 2007.10.16 22:58
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 찬우아빠
      2007.10.17 03:04
      똑같은 환경이 아니라서 제가 테스트는 못해봤습니다. 분산디비인경우 이렇게 쓸경우가 많을텐데 요즘 다...
    • 구창민
      2007.10.17 03:15
      오오.. 찬우아빠님 역시 디비고수.. 찬우아빠님 만쉐~~
    • 찬우아빠
      2007.10.17 03:16
      호곡.... ㅡㅡ
    • 메니아
    • 2007.10.16 04:23
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 성더기
      2007.10.16 19:16
      Project Option에 MainForm 을 확인해 보세요. MainForm이 DM으로 되어 있으면 프로세스가 남아 있을 ...
    • 최용일
      2007.10.15 21:19
      안녕하세요. 최용일입니다. DBGrid에는 그러한 기능이 없습니다. DBGrid는 Database에 있는 데이터를 표...
    • 이태윤
    • 2007.10.13 21:57
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2007.10.15 21:21
      안녕하세요. 최용일입니다. 소트를 하실려면 Index를 쓰시거나 TTable컴포넌트 대신에 TQuery컴포넌트를...
    • 김범진
    • 2007.10.13 05:48
    • 5 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2007.10.13 06:36
      안녕하세요. 최용일입니다. 프로그램내부에서 특별히 처리하지 않은한 키보드로 Ctrl+V를 누르나 keybd_...
    • 김범진
      2007.10.13 06:53
      의미 전달에 약간의 문제가 있었읍니다. ctrl + v도 안 되고 keybd_event도 물론 안 됩니다. 숫자와 엔...
    • 최용일
      2007.10.15 21:16
      keybd_event가 된다는 것인지 안된다는 것인지 알 수 없군요... 쩝~ 일단 keybd_event로 원하는 문자가 ...
    • 김범진
      2007.10.15 21:35
      고맙습니다. keybd_event가 숫자와 엔터 키 등의 경우에만 실행되고 ctrl 키 등에 대해서는 실행이 되지...
    • 최용일
      2007.10.16 00:14
      keybd_event로 숫자가 입력이 되면 원하는 기능은 되는것 아닌가요? 굳이 Ctrl+V로 붙여넣기를 할 이유가 ...
    • 김성일
    • 2007.10.13 02:20
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 왕초보
    • 2007.10.13 00:43
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 구창민
      2007.10.13 00:45
      안녕하세요.. 참고하시고 즐거운 프로그래밍 하세요.. http://www.delmadang.com/cwb-bin/CrazyWWWBo...
    • 이하영
    • 2007.10.12 07:10
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 구창민
      2007.10.12 19:35
      안녕하세요.. 아래 주소들이 힌트가 되었음 좋겠네요.. http://www.delphibbs.com/delphibbs/dispq.a...
    • 임우식
      2007.10.12 19:43
      용지설정부분이 A4 사이즈로 선택되어 있는데...어찌된 일인지 몰라도 용지선택하는곳 오른쪽의 수치가 엄...
    • 최용일
      2007.10.13 02:35
      핵심적인 기능은 단 두가지입니다. 카메라등의 장치에서 영상 소스를 캡춰해서 인코딩하는 것과 이것을 ...
    • 박찬우
      2007.10.16 20:30
      oncellchanging 은  ~ing 가 붙었지요 ? 그래서 변경되면 즉시 발생할껍니다.....그리하여 입...