Недавно написал прогу, которая в числе прочего не даёт запускаться двум экземплярам себя. Я это реализовал через атомы примерно так: Код (Text): .code start: invoke GetModuleHandleA,NULL mov hInst,eax invoke GlobalFindAtomA,addr AtomString cmp eax,0 jne exitapp invoke GlobalAddAtomA,addr AtomString mov Atom,eax ;register class: mov wcl.cbSize,sizeof wndclassex mov wcl.style,CS_HREDRAW+CS_VREDRAW mov wcl.lpfnWndProc,offset wndproc mov wcl.cbClsExtra,0 mov wcl.cbWndExtra,0 mov eax,hInst mov wcl.hInstance,eax invoke LoadIconA,eax,1 mov wcl.hIcon,eax invoke LoadCursorA,NULL,IDC_WAIT mov wcl.hCursor,eax mov wcl.hbrBackground,6 mov wcl.lpszMenuName,NULL mov wcl.lpszClassName,offset clsname mov wcl.hIconSm,NULL invoke RegisterClassExA,addr wcl cmp eax,NULL jne crwnd invoke MessageBoxA,NULL,addr msgerrtext,addr wndname,MB_OK+MB_ICONSTOP jmp overone exitapp: invoke MessageBoxA,NULL,addr alreadyexist,addr wndname,MB_OK+MB_ICONINFORMATION overone: invoke ExitProcess,1 crwnd: invoke CreateWindowExA,NULL,addr clsname,addr wndname,WS_OVERLAPPEDWINDOW,100,100,100,100,NULL,NULL,hInst,NULL mov hWnd,eax invoke ShowWindow,hWnd,SW_HIDE invoke PostMessage,hWnd,WM_SHOWWINDOW,NULL,NULL invoke UpdateWindow,hWnd mov flag,0 invoke SetTimer,hWnd,1,30000,NULL cmp eax,0 jne _loop invoke MessageBoxA,NULL,addr msgerrtext2,addr wndname,MB_OK+MB_ICONSTOP invoke ExitProcess,2 _loop: invoke GetMessageA,addr msg,NULL,0,0 cmp eax,0 je exitnormal invoke TranslateMessage,addr msg invoke DispatchMessageA,addr msg jmp _loop exitnormal: bt flag,0 jnc delex mov word ptr [temp],0a0dh invoke CreateFile, addr logname, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL cmp eax,-1 je _ferror2 mov hFile,eax invoke setFilePointer,hFile,0,NULL,FILE_END invoke WriteFile, hFile, addr temp, 2, addr rw, NULL invoke CloseHandle,hFile delex: invoke Shell_NotifyIconA,NIM_DELETE,addr tricon delatom: invoke GlobalDeleteAtom,Atom test eax,eax jz delatom jmp exit _ferror2: invoke MessageBox,NULL,addr ferr,addr wndname,MB_OK+MB_ICONEXCLAMATION jmp delex exit: invoke ExitProcess,0 Здесь привожу только ключевой участок кода. Проблема заключается в том, что у меня под Win98 всё работает как положено, а у друга под WinXP выводит тот самый "MessageBoxA,NULL,addr alreadyexist,addr wndname,MB_OK+MB_ICONINFORMATION". Может кто-нибудь знает почему так?
Great думается, непринципиально ибо добрая половина софта проверяет bool как eax а не al... и т.п. А другая половина устанавливает флаги через "+" а не через "OR". /хотя всё это не есть гуд/
Derebuser а оно так сразу стало выводится или первый запуск прошел нормально? Сам столкнулся с этой проблемой. Подозреваю, что после закрытия программы атом просто не уничтожается, поэтому перешел на мутексы
Нет, сообщение выводится при первом запуске. А что касается "неудалившегося" атома, то это маловероятно: Код (Text): delatom: invoke GlobalDeleteAtom,Atom test eax,eax jz delatom ;если получилось,удалять ещё jmp exit ;если не получилось, значит все такие атомы удалены Как видите, пресловутый атом удаляется довольно жёстко. А что такое мутексы и где про них можно почитать?
Код (Text): _mutex db 'some identifier',0 start: invoke OpenMutex,1F0001h,0,_mutex test eax,eax jne already_runin invoke CreateMutex,0,0,_mutex jmp next00 already_runin:
А атомы - глобальная штука. Они же создаются при регистрации класса окна. И хранятся в системе до явного удаления и MSoft про это заметил верно. так что чистый код рулит и ExitProcess cleanup'у тута не поможет.
Это принципиально и дело именно в этом, я проверил. Видно, они слегка криво реализованы и там не очищается старшая половина EAX перед выходом из GlobalFindAtomA.
Видно реализация такова, что в 98й случайно очищается, а в ХР нет. Говорят вот, что не обязано очищаться. Короче проверяй ax только.. старшую часть не трожь)
Можно ещё CreateMutex и уникальное имя использовать для этих целей. если после вызова GetLastError() скажет ERROR_ALREADY_EXISTS, то значит грузится 2й экземпляр.
Mental_Mirror Фриман дал правильный код Заблуждаешься. Что будет если первая копия процесса успеет выполнить только OpenMutex, винда передаст управление второй копии, которая успеет выполнить OpenMutex и CreateMutex?