如何使用Delphi检查进程是否正在运行?

发布于 2024-07-19 08:37:43 字数 224 浏览 6 评论 0 原文

与这个问题类似,但在Delphi中:

如何查明进程是否已使用 c# 运行?

我有一个更新程序,我希望它检查要更新的程序当前未运行,最好它会检查所有用户,不仅仅是当前用户。

Similar to this question, but in Delphi:

How do I find out if a process is already running using c#?

I have an updater program, I want it to check the program its about to update is not currently running, preferably it would check all users, not just current user.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

审判长 2024-07-26 08:37:43

来自: http://www.delphitricks.com/source-code/windows/check_if_a_process_is_running .html

uses TlHelp32; 

    function processExists(exeFileName: string): Boolean; 
var 
  ContinueLoop: BOOL; 
  FSnapshotHandle: THandle; 
  FProcessEntry32: TProcessEntry32; 
begin 
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32); 
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); 
  Result := False; 
  while Integer(ContinueLoop) <> 0 do 
  begin 
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = 
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = 
      UpperCase(ExeFileName))) then 
    begin 
      Result := True; 
    end; 
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); 
  end; 
  CloseHandle(FSnapshotHandle); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
  if processExists('notepad.exe') then 
    ShowMessage('process is running') 
  else 
    ShowMessage('process not running'); 
end;

from: http://www.delphitricks.com/source-code/windows/check_if_a_process_is_running.html

uses TlHelp32; 

    function processExists(exeFileName: string): Boolean; 
var 
  ContinueLoop: BOOL; 
  FSnapshotHandle: THandle; 
  FProcessEntry32: TProcessEntry32; 
begin 
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32); 
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); 
  Result := False; 
  while Integer(ContinueLoop) <> 0 do 
  begin 
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = 
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = 
      UpperCase(ExeFileName))) then 
    begin 
      Result := True; 
    end; 
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); 
  end; 
  CloseHandle(FSnapshotHandle); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
  if processExists('notepad.exe') then 
    ShowMessage('process is running') 
  else 
    ShowMessage('process not running'); 
end;
ゞ记忆︶ㄣ 2024-07-26 08:37:43

如果您正在编写一些自动更新代码,您还可以考虑与您的应用程序建立某种连接并告诉它自行关闭。

例如,这可能涉及向应用程序的主窗口发布一条消息,告诉它自行关闭。 或者打开IPC管道等。

If you're writing a bit of auto-updating code, you could also consider making a connection of some sort to your application and telling it to shut itself down.

This could e.g. involve posting a message to the main window of your application telling it to shut itself down. Or opening an IPC pipe etc.

冷心人i 2024-07-26 08:37:43
uses TlHelp32, PsAPI;

function ProcessExists(anExeFileName: string): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  fullPath: string;
  myHandle: THandle;
  myPID: DWORD;
begin
  // wsyma 2016-04-20 Erkennung, ob ein Prozess in einem bestimmten Pfad schon gestartet wurde.
  // Detection wether a process in a certain path is allready started.
  // http://stackoverflow.com/questions/876224/how-to-check-if-a-process-is-running-using-delphi
  // http://swissdelphicenter.ch/en/showcode.php?id=2010
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExtractFileName(anExeFileName)) then
    begin
      myPID := FProcessEntry32.th32ProcessID;
      myHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, myPID);
      if myHandle <> 0 then
      try
        SetLength(fullPath, MAX_PATH);
        if GetModuleFileNameEx(myHandle, 0, PChar(fullPath), MAX_PATH) > 0 then
        begin
          SetLength(fullPath, StrLen(PChar(fullPath)));
          if UpperCase(fullPath) = UpperCase(anExeFileName) then
            Result := True;
        end else
          fullPath := '';
      finally
        CloseHandle(myHandle);
      end;
      if Result then
        Break;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;
uses TlHelp32, PsAPI;

function ProcessExists(anExeFileName: string): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  fullPath: string;
  myHandle: THandle;
  myPID: DWORD;
begin
  // wsyma 2016-04-20 Erkennung, ob ein Prozess in einem bestimmten Pfad schon gestartet wurde.
  // Detection wether a process in a certain path is allready started.
  // http://stackoverflow.com/questions/876224/how-to-check-if-a-process-is-running-using-delphi
  // http://swissdelphicenter.ch/en/showcode.php?id=2010
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExtractFileName(anExeFileName)) then
    begin
      myPID := FProcessEntry32.th32ProcessID;
      myHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, myPID);
      if myHandle <> 0 then
      try
        SetLength(fullPath, MAX_PATH);
        if GetModuleFileNameEx(myHandle, 0, PChar(fullPath), MAX_PATH) > 0 then
        begin
          SetLength(fullPath, StrLen(PChar(fullPath)));
          if UpperCase(fullPath) = UpperCase(anExeFileName) then
            Result := True;
        end else
          fullPath := '';
      finally
        CloseHandle(myHandle);
      end;
      if Result then
        Break;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;
洒一地阳光 2024-07-26 08:37:43

如果您可以控制应用程序(正如您的问题所暗示的那样),那么一个很好的方法是在进程启动的早期创建一个命名文件映射对象。 这类似于 RedLEON 创建互斥体的建议。

// Add this into the application you wish to update
CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, 32, 'MAIN-PROGRAM');
// Note: Mapping object is destroyed when your application exits

// Add this into your updater application       
var
    hMapping: HWND;
begin
    hMapping := CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, 32, 'MAIN-PROGRAM');
    if (hMapping <> 0) then
        begin
        if (GetLastError() = ERROR_ALREADY_EXISTS) then
            ShowMessage('Application to update is already running!');
        end;

查看 有关 CreateFileMapping 的 MSDN 文档 了解更多详情。

另请参阅此问题的已接受答案,其中涵盖卢克的回答并提供了额外的解决方案。

If you have control over the application (as is implied from your question), a nice way to do this is to create a named file mapping object early in the process starts. This is similar to the suggestion of creating a mutex from RedLEON.

// Add this into the application you wish to update
CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, 32, 'MAIN-PROGRAM');
// Note: Mapping object is destroyed when your application exits

// Add this into your updater application       
var
    hMapping: HWND;
begin
    hMapping := CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, 32, 'MAIN-PROGRAM');
    if (hMapping <> 0) then
        begin
        if (GetLastError() = ERROR_ALREADY_EXISTS) then
            ShowMessage('Application to update is already running!');
        end;

Check out the MSDN documentation on CreateFileMapping for further details.

See also the accepted answer to this question which covers Luke's answer and provides additional solutions.

鯉魚旗 2024-07-26 08:37:43

我正在输入主单元初始化部分的这些代码。

initialization
mHandle := CreateMutex(nil, True, 'myApp.ts');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
  MessageDlg('Program already running!', mtError, [mbOK], 0);
  Halt;
end;

I' m typing these codes initialization part of main unit.

initialization
mHandle := CreateMutex(nil, True, 'myApp.ts');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
  MessageDlg('Program already running!', mtError, [mbOK], 0);
  Halt;
end;
感情旳空白 2024-07-26 08:37:43

检查应用程序是否已在运行。 感谢这个 & @RedLEON 用户。

program Project1;

uses
  Vcl.Forms,
  Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

var
  MutexHandle: THandle;
  hPrevInst: Boolean;

begin
  // -== Check to see if the named mutex object existed before this call ==-
  MutexHandle := CreateMutex(nil, True, 'MysampleAppMutex');
  if MutexHandle <> 0 then
  begin
    if GetLastError = ERROR_ALREADY_EXISTS then
    // -== set hPrevInst property and close the mutex handle ==-
    begin
      MessageBox(0, 'Instance of this application is already running.', 'Application already running', mb_IconHand);

      hPrevInst := True;
      CloseHandle(MutexHandle);
      // 'Halt' Is the actual one that prevents a second instance
      Halt;
      // of your app from running.
    end
    else
    begin
      // -== indicate no previous instance was found ==-
      hPrevInst := False;
    end;
  end
  else
  begin
    // -== indicate no previous instance was found ==-
    hPrevInst := False;
  end;
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;

end.

Check application is already running. thanks from this & @RedLEON user.

program Project1;

uses
  Vcl.Forms,
  Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

var
  MutexHandle: THandle;
  hPrevInst: Boolean;

begin
  // -== Check to see if the named mutex object existed before this call ==-
  MutexHandle := CreateMutex(nil, True, 'MysampleAppMutex');
  if MutexHandle <> 0 then
  begin
    if GetLastError = ERROR_ALREADY_EXISTS then
    // -== set hPrevInst property and close the mutex handle ==-
    begin
      MessageBox(0, 'Instance of this application is already running.', 'Application already running', mb_IconHand);

      hPrevInst := True;
      CloseHandle(MutexHandle);
      // 'Halt' Is the actual one that prevents a second instance
      Halt;
      // of your app from running.
    end
    else
    begin
      // -== indicate no previous instance was found ==-
      hPrevInst := False;
    end;
  end
  else
  begin
    // -== indicate no previous instance was found ==-
    hPrevInst := False;
  end;
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;

end.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文