Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Заставить работать CreateFileMapping глобально


Автор: Delphist 25.1.2008, 16:02
Для запуска одной копии программы я настарте делаю такую вещь:

Код

function CheckAppRun: integer;
var
  Map: THandle;  
begin
  Map := CreateFileMapping($FFFFFFFF, nil, PAGE_READONLY, 0, 32, '{DA2380A2-EEDD-438F-11F8-ADEE5F6B3638}');
  if Map = 0 then
    Result := -1
  else if GetLastError = ERROR_ALREADY_EXISTS then
    Result := 1 //прога уже запущена
  else
    Result := 0
end;


Прикол в том, что данные фишка перестает работать, если я делаю так: загружаюсь в WinXP под обычным пользователем запускаю свою прогу под текущим пользователем, а затем запускаю прогу от имени админа и в результате запускается вторая копия проги, как это предотвратить, т.е. заставить CreateFileMapping создавать глобальный handle, т.е. чтобы всегда моглы быть запущено не более одной копии программы.
Тот же самый вопрос и для OpenMutex. 
И еще один вопросик, каким лучше пользоваться способом CreateFileMapping или OpenMutex для запуска одной копии проги. 

Автор: MetalFan 25.1.2008, 18:38
тебе уже ответили на другом форуме.
попробуй добавить к началу имени маппинга 'Global\'

Автор: bems 25.1.2008, 18:44
проверь версию виндов и если она >=2000 тогда создавай с именем 'Global\{DA2380A2-EEDD-438F-11F8-ADEE5F6B3638}'

это необходимая часть. Если окажется недостаточным установи вместо nil реальную SECURITY_ATTRIBUTES в которой не нулевой lpSecurityDescriptor, для которого функцией SetSecurityDescriptorDacl поставь DACL равный nil. Это предоставит всем полный доступ к объекту.
Но если мне не изменяет память даже если нет доступа, а объект существует то GetLastError вернет ERROR_ALREADY_EXISTS и с правами можно не дергаться. Короче, проверь smile

Добавлено через 1 минуту и 43 секунды
Цитата(Delphist @  25.1.2008,  16:02 Найти цитируемый пост)
каким лучше пользоваться способом CreateFileMapping или OpenMutex для запуска одной копии 
суть одна и та же, но мютекс поменьше будет. А еще лучше наверное event.

Добавлено через 7 минут и 31 секунду
процедуру перелай так
Код

function CheckAppRun: integer;
var
  Map: THandle;  
begin
  SetLastError(0);
  Map := CreateFileMapping($FFFFFFFF, nil, PAGE_READONLY, 0, 32, 'Global\{DA2380A2-EEDD-438F-11F8-ADEE5F6B3638}');
  if GetLastError=ERROR_ALREADY_EXISTS 
     then begin
             Result:=1;
             if Map=0 then CloseHandle(Map);
             end
     else Result:=0;       
  end;

Автор: Delphist 25.1.2008, 19:26
Цитата(MetalFan @  25.1.2008,  19:38 Найти цитируемый пост)
тебе уже ответили на другом форуме.
попробуй добавить к началу имени маппинга 'Global\' 

И на том же форуме я ответил, что не помагает.

Автор: MetalFan 25.1.2008, 19:43
может попробовать выставить себе права SeCreateGlobalPrivilege

Добавлено через 3 минуты и 15 секунд
стоп.

Цитата(Delphist @  25.1.2008,  19:26 Найти цитируемый пост)
что не помагает. 

объясни точнее, что тебе надо добиться от файломаппинга???
чтобы он был доступен из разных сессий?

Автор: Delphist 25.1.2008, 21:30
Цитата(MetalFan @  25.1.2008,  20:43 Найти цитируемый пост)
объясни точнее, что тебе надо добиться от файломаппинга???
чтобы он был доступен из разных сессий? 

Мне нужно через файл маппинг сделать чтобы всегда запускалось не более одной копии проги. Это не получается сделать если прога запускается под разными пользователями

Автор: MetalFan 26.1.2008, 00:27
понятно. и что с применением всех описанных ранее условий происходит?
что и в какой момент возвращает GetLastError?

Автор: Delphist 28.1.2008, 11:25
Цитата(bems @  25.1.2008,  19:44 Найти цитируемый пост)
процедуру перелай так
код Pascal/Delphi
function CheckAppRun: integer;
var
  Map: THandle;  
begin
  SetLastError(0);
  Map := CreateFileMapping($FFFFFFFF, nil, PAGE_READONLY, 0, 32, 'Global\{DA2380A2-EEDD-438F-11F8-ADEE5F6B3638}');
  if GetLastError=ERROR_ALREADY_EXISTS 
     then begin
             Result:=1;
             if Map=0 then CloseHandle(Map);
             end
     else Result:=0;       
  end;

Не фига не работает.

Добавлено через 58 секунд
Цитата(MetalFan @  26.1.2008,  01:27 Найти цитируемый пост)
понятно. и что с применением всех описанных ранее условий происходит?
что и в какой момент возвращает GetLastError? 

GetLastError возворатит 0 при запуске второй копии проги от имени другого пользователя

Автор: EvilsInterrupt 30.1.2008, 12:18
Код

var
  hMutex        : THandle;
  CannotRunMsg  : string;

function IsApplicationRun : Boolean;
begin
  Result := False;
  hMutex := CreateMutex(nil, True,
            PChar(AnsiReplaceText(Application.ExeName,'\','/')));
  if  GetLastError = ERROR_ALREADY_EXISTS then
      Result := True;
end;


Попробуй-ка, может чего интересного увидешь.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)