Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 2003.02.03;
Скачать: [xml.tar.bz2];

Вниз

OneInstance, но не простой...   Найти похожие ветки 

 
LordOfSilence   (2002-11-18 13:56) [0]

Коллеги, подскажите, пожалуйста, а то что-то ничего
путного в голову не идет.
Описываю ситуацию:
В свою время мой шеф поставил мне задачу по написанию
небольшой проги-утилитки. Если кому интересно - сбор
данных с COM-порта и ведение логов. Сейчас эта прога
мирно сидит в систрее нашего сервера и тихонько ведет
свою работу в фоновом режиме. По сути задачи посчитал
необходимым реализовать OneInstance. Сделал это через
Mutex. Если будет необходимо - выложу кусок исходного
кода. До этого момента все было в порядке и проблем не
возникало. Но!...
Мой шеф - весьма продвинутый малый и любит лезть на
сервер через терминальный доступ, для чего использует
Citrix. Так вот, когда он коннектится к серверу, то
моя программа стартует (в его терминальной сессии),
так как ярлык прописан в папке автозагрузки, и...
НЕ НАХОДИТ первый экземпляр, который уже сидит в систрее,
при этом ругается на то, что COM-порт уже занят, после
чего главное окно приложения пропадает, но само приложение
остается висеть в списке процессов сервера, в чем мы
убедились, просмотрев список этих процессов на самом сервере.
То есть, как я понимаю, в этом случае запускаемые задачи разносятся по разным "пространствам" и Mutex не ловится.
Как посоветуете решать эту нестыковку? Проверять при старте
состояние COM-порта (хоть убей, но почему-то этот способ
мне не кажется "изящным") или тупо создавать некий внешний
файл "блокировки", который будет создаваться при старте
первого экземпляра и уничтожаться соответственно только
при его завершении, а во втором проверять его существование?
А может быть существует другой оригинальный способ,
о котором я и не подозреваю?

Помогите, пожалуйста, разрулить эту ситуацию, а то у меня
сегодня "синий понедельник"...


 
sndanil   (2002-11-18 14:26) [1]

а про сервис ты не думал?


 
han_malign   (2002-11-18 14:29) [2]

Mutex - именованный?


 
LordOfSilence   (2002-11-18 14:33) [3]

Про сервис думал. Но это переписывать надо.
Не все, конечно, но пальчикам придется попорхать :)
Хотел отделаться "легким испугом".

program ComLog;

uses
Forms,
Windows,
SysUtils,
main in "main.pas" {frmMain},
setup in "setup.pas" {frmSetup},
engine in "engine.pas";

var
Mutex : THandle;
IsPrevInst : boolean;
PrevInst : hWnd;

{$R *.res}

begin
Mutex := CreateMutex( nil, False, "ComLogMutex" );
if Mutex <> 0 then begin
if GetLastError = ERROR_ALREADY_EXISTS then begin
IsPrevInst := True;
CloseHandle( Mutex );
end
else IsPrevInst := False;
end
else IsPrevInst := False;
if not IsPrevInst then begin
Application.Initialize;
Application.Title := "Утилита ведения логов COM-порта";
Application.CreateForm(TfrmMain, frmMain);
Application.CreateForm(TfrmSetup, frmSetup);
Application.Run;
end
else begin
PrevInst := FindWindow( ClassName, AppTitle );
if PrevInst <> 0 then PostMessage( PrevInst, UM_APPRESTORE, 0, 0 )
end
end.


 
han_malign   (2002-11-18 14:46) [4]

If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Ни где то же имя не иcпользуется?


 
LordOfSilence   (2002-11-18 14:56) [5]

To han_malign © (18.11.02 14:46)

Извините, что-то не догоняю Вашу мысль.
Нельзя ли по-подробнее ее раскрыть.
Говорю же - туповатый сегодня какой-то...


 
Ketmar   (2002-11-18 15:08) [6]

да. только что проверил: похоже, что для разных логонов разные NameSpaces. по крайней мере, мютексовые. отлично оба раза сказала, что все оки-доки, и создала мьютексы. %-(
лень проверять, но: а как с глобальными атомами (это не дело, однако - а вдруг получится? хотя с атомами глюки другого рода: ваша программа может помереть, забыв убить атом, и он до перезагрузки останется в системе. сами понимаете, чем это чревато).
еще можно проверить pipes и mapped files. хоть что-то да должно заработать! %-) я полагаю, что и пайпы, и named files будут. однако, честно говоря, я то же самое и про мьютексы думал %-( %-)

Satanas Nobiscum! 18-Nov-XXXVII A.S.


 
Игорь Шевченко   (2002-11-18 15:12) [7]

Файл - лучше всего. Создать при старте и удалять при завершении. Mutex"ы они могут быть свои для каждого терминального сеанса (не уверен).


 
han_malign   (2002-11-18 15:16) [8]

PrevInst := FindWindow( ClassName, AppTitle );
if PrevInst <> 0 then PostMessage( PrevInst, UM_APPRESTORE, 0, 0 )
уже есть проверка, чаще всего так и делается.


 
LordOfSilence   (2002-11-18 15:34) [9]

To Ketmar © (18.11.02 15:08)
Да и я как-то всегда полагал, что Mutex"ы понадежнее
атомов будут :)

To Игорь Шевченко © (18.11.02 15:12)
Угу... я уже начинаю склоняться к этой же мысли.
Как говорил Лёлик, "зато дешево и практично" :)
Кстати, только-что шеф озвучил мысль, что сервис
все равно писать придется. Ибо если уже его шеф
(наш финансовый директор) удаленно из дому залезет
на сервер и вдруг его (сервер) "нечаянно" свалит,
то после перезагрузки, блин, сервака надо, чтобы
запись логов стартовала до того, как он полностью
загрузится независимо от того, знает юзер пароль
к сервачине или нет.
Тьфу... Короче, ребята, у меня гемморой на ровном
месте. А все потому, что всяким продвинутым товарищам
руки дома некуда приложить.

To han_malign © (18.11.02 15:16)
Не, все-таки вариант с Mutex"ами как-то понадежнее и
стабильнее, ИМХО. Да и все-равно в моем случае это
не поможет. Как я найду заголовок окна из другой сессии?


 
Ketmar   (2002-11-18 16:02) [10]

с файлами та же фигня, что и с атомами - а кто его убьет, ежели программа забыла/не смогла (ну упала, болезная. вместе с виндой %-)?

2han_malign:
FindWindow - криво и потенциально зависабельно (читаем Рихтера).

Satanas Nobiscum! 18-Nov-XXXVII A.S.


 
LordOfSilence   (2002-11-18 16:17) [11]

To Ketmar © (18.11.02 16:02)
Полностью согласен, но, с другой стороны, если моя
программа "забыла/не смогла" убить лок-файл, то я,
по крайней мере, могу своему шефу всегда сказать
какой файл надо убивать ручками, чтобы эта дрянь
все же запустилась... :(((

P.S. Видать и вправду, Сатана сегодня со мной :)


 
LordOfSilence   (2002-11-18 16:30) [12]

Кстати, только что промелькнула такая идея:

1. При старте создаю файл и открываю его
с экслюзивными правами.
2. При завершении приложения соответственно его убиваю.
3. При старте второго терминального экземпляра
пытаюсь этот файл убить. Если удается - гружусь,
если нет - стало быть первый экземпляр еще жив
вместе с Виндой.

Как полагаете, а?

P.S. Я, наверное, уже задолбал вас всех сегодня
своими заморочками...


 
Ketmar   (2002-11-18 17:03) [13]

тоже вариант. а может, все же, попробовать pipes/mmaped files? %-)

Satanas Nobiscum! 18-Nov-XXXVII A.S.


 
LordOfSilence   (2002-11-18 17:11) [14]

Может... Надо подумать.
А может лучше начальникам "дать гвоздей"?
А еще лучше самому становиться начальником! :)


 
Игорь Шевченко   (2002-11-19 13:51) [15]

Ketmar © (18.11.02 17:03)

А зачем делать сложно, когда можно сделать просто ? :-)

С уважением,


 
Александр Павлов   (2002-11-20 11:20) [16]

Вот что по этому поводу думает дюдя Джеффри Рихтер(Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows, Глава 3):


Пространства имен Terminal Server

На машине с Terminal Server существует множество пространств имен для объектов ядра. Объекты, которые должны быть доступны всем клиентам, используют одно глобальное пространство имен. (Такие объекты, как правило, связаны с сервисами, предоставляемыми клиентским программам.) В каждом клиентском сеансе формируется свое пространство имен, чтобы исключить конфликты между несколькими сеансами, в которых запускается одно и то же приложение Ни из какого сеанса нельзя получить доступ к объектам другого сеанса, даже если у их объектов идентичные имена.

Именованные объекты ядра, относящиеся к какому-либо сервису, всегда находятся в глобальном пространстве имен, а аналогичный объект, связанный с приложением, Terminal Server по умолчанию помещает в пространство имен киентского сеанca. Однако и его можно перевести в глобальное пространство имен, поставив перед именем объекта префикс "Global\", как в примере ниже.

HANDLE h = CreateEvenL(NULL, FALSE, FALSE, "Global\\MyName");

Если Вы хотите явно указать, что объект ядра должен находиться в пространстве имен клиентского сеанса, используйте префикс "Local\":

HANDLE h = CreateEvent(NULL, FALSE, FALSE, "Local\\MyName");

Microsoft рассматривает префиксы Global и Local как зарезервированные ключевые слова, которые не должны встречаться в самих именах объектов. К числу таких слов Microsoft относит и Session, хотя на сегодняшний день оно не связано ни с какой функциональностью. Также обратите внимание на две вещи, все эти ключевые слова чувствительны к регистру букв и игнорируются, если компьютер работает без Terminal Server.



 
LordOfSilence   (2002-11-20 11:47) [17]

Большое спасибо за пищу для размышлений.
Уже не ожидал, что кто-то еще поднимет эту ветку...
Надо будет поэкспериментировать!


 
Александр Павлов   (2002-11-20 12:32) [18]

Как говорят америкосы - you wellcome... :)


 
LordOfSilence   (2002-11-21 12:08) [19]

To Александр Павлов © (20.11.02 11:20)

Метод, предложенный Вами оказался действенным!

Простого изменения вышеуказанного вызова создания мьютекса
на следующий оказалось достаточно для решения моей проблемы:

Mutex := CreateMutex( nil, False, "Global\ComLogMutex" );

От лица самого себя выражаю Вам огромную благодарность! :)


 
paul_shmakov   (2002-11-21 17:00) [20]

я уже давно предлагал в на странице форума "winapi" и "система" сделать что-то типа "Читайте Рихтера!!! Экономьте нервы и здоровье" и ссылку дать ;)


 
Antonius   (2002-11-21 21:46) [21]

А где ссылка то ? :)


 
paul_shmakov   (2002-11-22 13:01) [22]

2 Antonius:

Джеффри Рихтер. Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

электронная версия:
http://www.podgoretsky.com/
Прочее\Языки программирования\Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows

бумажная версия
http://www.books.ru/shop/books/8283


 
Antonius   (2002-11-22 15:43) [23]

Вот спасибо!



Страницы: 1 вся ветка

Форум: "Система";
Текущий архив: 2003.02.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.011 c
1-4963
OxOTHuK
2003-01-26 21:46
2003.02.03
Откат


1-4948
Алексей П
2003-01-26 18:55
2003.02.03
Word


7-5290
Newe
2002-11-21 15:24
2003.02.03
Как программно узнать когда юзер вставит в дисковод дискету?


6-5117
neodiX
2002-12-07 15:50
2003.02.03
Изменение размера пакета TCP


3-4737
Дима2003
2003-01-15 11:44
2003.02.03
FormatDateTime и TQSL





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский