У меня есть программа обновления, я хочу, чтобы она проверила, что программа, которую он собирается обновить, в настоящее время не запущена, желательно, чтобы она проверяла всех пользователей, а не только текущего пользователя.
Robo 18 Май 2009 в 08:12
5 ответов
Лучший ответ
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;
Luke Schafer 18 Май 2009 в 08:18
Если вы пишете немного автообновляющегося кода, вы также можете подумать о том, чтобы установить какое-то соединение с вашим приложением и сказать ему, чтобы оно закрылось.
Delphi DS150 PRO Diagnostic Scanner with Bluetooth — Test
Это могло бы, например, вовлекать размещение сообщения в главном окне вашего приложения, говорящего о том, чтобы оно закрылось. Или открытие трубы IPC и т. Д.
Conor Boyd 18 Май 2009 в 08:52
Если у вас есть контроль над приложением (как следует из вашего вопроса), хороший способ сделать это — создать именованный объект сопоставления файлов на раннем этапе запуска процесса. Это похоже на предложение создать мьютекс от 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;
Ознакомьтесь с документацией MSDN по CreateFileMapping для получения дополнительной информации.
См. Также принятый ответ на этот вопрос, который охватывает Люк отвечает и предлагает дополнительные решения.
Community 23 Май 2017 в 15:10
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;
Wolfgang Syma 20 Апр 2016 в 16:50
Я набираю эти коды инициализационной части основного блока.
Delphi DS150E, Autocom, Multidiag — диагностический сканер с Aliexpress
initialization mHandle := CreateMutex(nil, True, ‘myApp.ts’); if GetLastError = ERROR_ALREADY_EXISTS then begin MessageDlg(‘Program already running!’, mtError, [mbOK], 0); Halt; end;
Источник: question-it.com
delphi: как проверить, запущено ли приложение и закрыть дубликат экземпляра? [Дубликат]
все varchar, которые имеют более 200, заменяют их 191 или устанавливают их текст.
задан Toby Allen 22 January 2013 в 01:41
12 ответов
Вы можете создать Семафор и прекратить выполнение (поместите код в ваш файл * .dpr) и принесите запущенное приложение на экран.
var Semafor: THandle; begin < Don’t start twice . if already running bring this instance to front >Semafor := CreateSemaphore(nil, 0, 1, ‘MY_APPLICATION_IS_RUNNING’); if ((Semafor <> 0) and < application is already running >(GetLastError = ERROR_ALREADY_EXISTS)) then begin RestoreWindow(‘TMyApplication’); CloseHandle(Semafor); Halt; end; Application.CreateForm(. ); Application.Initialize; Application.Run; CloseHandle(Semafor); end;
EDIT (добавлен метод RestoreWindow ). :
aFormName — это имя вашего основного класса формы в вашем приложении.
procedure RestoreWindow(aFormName: string); var Wnd, App: HWND; begin Wnd := FindWindow(PChar(aFormName), nil); if (Wnd <> 0) then begin < Set Window to foreground >App := GetWindowLong(Wnd, GWL_HWNDPARENT); if IsIconic(App) then ShowWindow(App, SW_RESTORE); SetForegroundwindow(App); end; end;
ответ дан kobik 17 August 2018 в 09:09
это greate, но я не могу получить Восстановить окно (‘MyApplication’) работать я должен реализовать это или мне нужно использовать блок, который я в настоящее время не использую – Arthur 20 January 2009 в 21:23
считывание по «процедуре RestoreWindow (WinHandle: HWND); поскольку мне нужен дескриптор aplicaton, который запускался сначала, мне нужно получить дескриптор приложения, который имеет удержание на семафоре. не уверен, что это новый вопрос или расширение – Arthur 20 January 2009 в 21:53
Ups . забыл добавить метод RestoreWindow, . отредактирует ответ – Drejc 20 January 2009 в 21:57
Не знаю, если я получаю форму Name неправильно, но она не открывает старый экземпляр. – Arthur 21 January 2009 в 02:08
Я думаю, что у нас есть случай ползучести. Вы много обитаете в части RestoreWindow ответа. Если вы хотите получить более подробную информацию об этом, я советую вам найти или задать другой вопрос: «Как сделать один экземпляр моей программы активировать другой?». – Rob Kennedy 21 January 2009 в 21:33
В прошлом я использовал сокет для одновременного запуска нескольких экземпляров. Если сокет используется, не продолжайте программу, если она доступна, пусть все работает как обычно.
ответ дан ahanson 17 August 2018 в 09:09
Я хотел бы добавить один пункт к превосходному ответу Роба Кеннеди (кроме того, что было бы лучше сделать функцию из своего кода, а не копировать все в DPR файл. Вам нужны только два параметра, имя мьютекса и логическое значение, должно ли mutext быть для каждого пользователя или общесистемного).
В ответе не уделяется много внимания наименованию мьютекс. Если вы ожидаете, что ваша программа будет установлена через Inno Setup (и, возможно, другие инструменты настройки тоже), вы должны тщательно выбрать имя, так как мьютекс можно использовать, чтобы программа установки проверяла, запущена ли в данный момент приложение, и предупредите пользователя, что они должны закрыть все экземпляры приложения. Если вы решите разрешить один экземпляр программы на пользователя, вам может понадобиться создать второй общесистемный мьютекс, так как для установки файлов может потребоваться отсутствие запущенных экземпляров приложения. Имя, которое должно использоваться для синхронизации с установщиком InnoSetup, должно быть жестко запрограммировано.
ответ дан Community 17 August 2018 в 09:09
Вы можете просто использовать функцию api для окна FindWindow. В классе delphi имя окна совпадает с именем класса, вы можете переопределить имя класса, переопределив функцию CreateParams. Чтобы проверить, существует ли окно, добавить код до создания основного окна, перед Application.Initialize;
Program test var handle :HWND; begin handle := FindWindow(‘TMySuperApp’, nil); if IsWindow(handle) then begin //app is running exit; end. Application.Initialize; Application.CreateForm(TMySuperApp, SuperApp); Application.Run; end;
ответ дан Edin Omeragic 17 August 2018 в 09:09
Какие единицы это использование HWND и findwindow не были распознаны. также будет работать, если мое «окно» скрыт в icontray? – Arthur 20 January 2009 в 04:19
Это потребует «Windows». Это полезное дополнение к Mutex, поскольку вы можете перенести предыдущее окно на передний план. Но если пользователь дважды откроет ваше приложение, первый, возможно, еще не открыл его окно, и поэтому он может быть пропущен. – mj2008 20 January 2009 в 10:36
Управление количеством экземпляров приложения:
ответ дан g2mk 17 August 2018 в 09:09
См. этот блок (с помощью CreateMutex): UiApp
Кроме того, на этой странице вы можете прочитать преимущества и недостатки этой работы с различными методами (mutex, FindWindows, . ).
У этого устройства есть решение активировать предыдущий экземпляр приложения, когда оно обнаружено.
С уважением и извини меня за мой плохой английский.
Neftalí -Germán Estévez —
ответ дан Germán Estévez -Neftalí- 17 August 2018 в 09:09
Я бы сказал, что есть несколько различных стратегий, которые вы можете использовать. Но самый простой (а не специфичный для платформы) — это тот, который вы сами предложили, а именно: в начале проверки программы проверьте, есть ли файл блокировки, созданный в наборе, конкретное местоположение. Если этот файл блокировки существует, то другой экземпляр уже запущен, если он не существует, то нет другого экземпляра. Когда ваша программа выходит, вы удаляете файл блокировки.
Однако, используя эту стратегию, у вас есть другая проблема, что произойдет, если ваша программа выйдет из строя? Файл блокировки по-прежнему сохраняется, и этот конкретный случай необходимо обработать.
Другая стратегия — это общесистемное решение мьютекса, в котором вы регистрируете свое присутствие в операционной системе (или это также правдоподобно, что это сделано автомагически). Когда второй экземпляр пытается запустить, он проверяет, есть ли уже активный процесс с определенным идентификатором. Если он уже существует, второй процесс выбирает не запускать и, при необходимости, фокусирует первое окно процесса (если рассматриваемый процесс владеет окном).
Однако эта стратегия является специфичной для платформы , и реализация будет отличаться от платформы к платформе.
Источник: legkovopros.ru
Ищете код Delphi 7, чтобы определить, запущена ли программа с правами администратора?
Функция оболочки Shell32 устарела; это хорошо, потому что это просто обертка вокруг другого кода, который вы все равно можете вызвать самостоятельно:
function IsUserAdmin: Boolean;
var
b: BOOL;
AdministratorsGroup: PSID;
begin
This function returns true if you are currently running with admin privileges.
In Vista and later, if you are non-elevated, this function will return false
(you are not running with administrative privileges).
If you *are* running elevated, then IsUserAdmin will return true, as you are
running with admin privileges.
Windows provides this similar function in Shell32.IsUserAnAdmin.
But the function is deprecated, and this code is lifted
from the docs for CheckTokenMembership:
http://msdn.microsoft.com/en-us/library/aa376389.aspx
>
Routine Description: This routine returns TRUE if the callers
process is a member of the Administrators local group. Caller is NOT
expected to be impersonating anyone and is expected to be able to
open its own process and process token.
Arguments: None.
Return Value:
TRUE — Caller has Administrators local group.
FALSE — Caller does not have Administrators local group.
>
b := AllocateAndInitializeSid(
SECURITY_NT_AUTHORITY,
2, //2 sub-authorities
SECURITY_BUILTIN_DOMAIN_RID, //sub-authority 0
DOMAIN_ALIAS_RID_ADMINS, //sub-authority 1
0, 0, 0, 0, 0, 0, //sub-authorities 2-7 not passed
AdministratorsGroup);
if (b) then
begin
if not CheckTokenMembership(0, AdministratorsGroup, b) then
b := False;
FreeSid(AdministratorsGroup);
end;
Result := b;
end;
Другими словами: эта функция дает вам ответ, который вы хотите: может ли пользователь обновлять файлы программы.
Вам нужно быть усталым от кода, который проверяет, являетесь ли вы членом группы «Администратор» . Вы можете быть частью группы «Администратор» , но не иметь никаких административных прав. Вы также можете иметь административные привилегии, но не быть частью группы «Администратор» .
Источник: progi.pro