Я исправил эту проблему с помощью:
varchar (200)
заменен на
varchar (191)
все varchar, которые имеют более 200, заменяют их 191 или устанавливают их текст.
Вы можете создать Семафор и прекратить выполнение (поместите код в ваш файл * .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;
В прошлом я использовал сокет для одновременного запуска нескольких экземпляров. Если сокет используется, не продолжайте программу, если она доступна, пусть все работает как обычно.
Я хотел бы добавить один пункт к превосходному ответу Роба Кеннеди (кроме того, что было бы лучше сделать функцию из своего кода, а не копировать все в DPR файл. Вам нужны только два параметра, имя мьютекса и логическое значение, должно ли mutext быть для каждого пользователя или общесистемного).
В ответе не уделяется много внимания наименованию мьютекс. Если вы ожидаете, что ваша программа будет установлена через Inno Setup (и, возможно, другие инструменты настройки тоже), вы должны тщательно выбрать имя, так как мьютекс можно использовать, чтобы программа установки проверяла, запущена ли в данный момент приложение, и предупредите пользователя, что они должны закрыть все экземпляры приложения. Если вы решите разрешить один экземпляр программы на пользователя, вам может понадобиться создать второй общесистемный мьютекс, так как для установки файлов может потребоваться отсутствие запущенных экземпляров приложения. Имя, которое должно использоваться для синхронизации с установщиком InnoSetup, должно быть жестко запрограммировано.
Вы можете просто использовать функцию 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;
См. этот блок (с помощью CreateMutex): UiApp
Кроме того, на этой странице вы можете прочитать преимущества и недостатки этой работы с различными методами (mutex, FindWindows, ...).
У этого устройства есть решение активировать предыдущий экземпляр приложения, когда оно обнаружено.
С уважением и извини меня за мой плохой английский.
Neftalí -Germán Estévez -
Я бы сказал, что есть несколько различных стратегий, которые вы можете использовать. Но самый простой (а не специфичный для платформы) - это тот, который вы сами предложили, а именно: в начале проверки программы проверьте, есть ли файл блокировки, созданный в наборе, конкретное местоположение. Если этот файл блокировки существует, то другой экземпляр уже запущен, если он не существует, то нет другого экземпляра. Когда ваша программа выходит, вы удаляете файл блокировки.
Однако, используя эту стратегию, у вас есть другая проблема, что произойдет, если ваша программа выйдет из строя? Файл блокировки по-прежнему сохраняется, и этот конкретный случай необходимо обработать.
Другая стратегия - это общесистемное решение мьютекса, в котором вы регистрируете свое присутствие в операционной системе (или это также правдоподобно, что это сделано автомагически). Когда второй экземпляр пытается запустить, он проверяет, есть ли уже активный процесс с определенным идентификатором. Если он уже существует, второй процесс выбирает не запускать и, при необходимости, фокусирует первое окно процесса (если рассматриваемый процесс владеет окном).
Однако эта стратегия является специфичной для платформы , и реализация будет отличаться от платформы к платформе.
Обычным решением является создание именованного общесистемного мьютекса.
Я не предоставил код как я не знаю Дельфи. Я могу предоставить код C #, если бы это было бы полезно.
Для этой цели имеется многопользовательский JVCL . См. «TJvAppInstances».