Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.217.65.190] |
|
Сообщ.
#1
,
|
|
|
Для управления службой из своего приложения пишу компонент. Он позволяет подключить к себе 1 TLabel (Статус), 4 TAction (Старт, Стоп, Пауза, Рестарт), 1 TComboBox (тип запуска). Жду от Вас пожеланий, замечаний и критики. На sourceforge.net. Все отзывы прошу оставлять здесь или на форже.
Прикреплённый файлzsvcpack10189.zip (22,45 Кбайт, скачиваний: 243) |
Сообщ.
#2
,
|
|
|
Технические замечания:
1. Не понятна конструкция (главное в чём отличие) ? procedure TSvcControler.SetActionSet(AValue: TSvcActionSet); begin if Assigned(AValue) then begin FActionSet := AValue; // это выполняется FActionSet.Controler := (Self); if AValue <> nil then AValue.FreeNotification(Self); end else FActionSet := AValue; // Или это выполняется end; 2. А где RemoveFreeNotification ? procedure TSvcControler.SetComboRunType(AValue: TComboBox); begin if FComboRunType <> AValue then begin FComboRunType := AValue; if AValue <> nil then begin AValue.FreeNotification(Self); UpdateCombo; end; end; end; 3. А таймер остановить ? procedure TSvcControler.UpdateStatus; var vSvcInfo: TSvcInfo; begin if Assigned(FOnBeforeStatusUpdate) then FOnBeforeStatusUpdate(Self); 4. Лучше использовать TCustomAction. published property Start: TAction index 0 read FStartAction write SetAction; 5. Не мешало бы функцию получения списка сервисов, зависимости сервисов |
Сообщ.
#3
,
|
|
|
[to DimaBr]
Здрасти! 1. Мифический код. Возможно, что просто пропустил, когда else дописывал. 2. Блин, забыл. Допишу RemoveFreeNotification. 3. А зачем таймер останавливать? Он же должен все время работать, пока существует компонент. 4. Весомое замечание. Поправлю. Спасибо. Просто раньше я его написал с привязкой к TCustomButton, потом решил на Actionы перевести, проверил-работает-оставил как есть. 5. Согласен, все упирается во время, для тех служб которые написаны под собственные нужды, зависимости пока не нужны, хотя если взять виндовую службу с зависимостями порой не понятно почему она не запускается, да просто служба не запущена, от которой она зависима. Вот только в отпуск пойду... Спасибо огромное за помомщь!!! |
Сообщ.
#4
,
|
|
|
3 Если событие пользователя затянется на время большее по таймеру, тогда что произойдет ? Таймер нужно остановить, вызвать событие пользователя, а потом снова запустить. Или же, если это таймер времени, то как то фиксировать что пользовательское событие ещё не завершено и повторный заход в него нежелателен.
|
Сообщ.
#5
,
|
|
|
Теперь понял. Спасибо, поправлю.
|
Сообщ.
#6
,
|
|
|
Имхо так будет правильнее
FLabel: TCustomLabel; FComboRunType: TCustomComboBox; Добавлено Вот процедура которая заполняет TTreeView "зависимостями" function GetDependenceService(const sMachine, key: string): PQueryServiceConfig; var schm: SC_Handle; // service control manager handle hService: SC_Handle; cbBuffSize, pcbBytesNeeded: DWORD; lpServiceConfig: PQueryServiceConfig; begin Result := nil; schm := OpenSCManager(PChar(sMachine), Nil, SC_MANAGER_ALL_ACCESS); // if successful... if(schm > 0)then begin // Для дополнительной информаци по сервису получаем описатель сервиса hService := OpenService(schm, PChar(key), SERVICE_QUERY_CONFIG); if hService <> 0 then try QueryServiceConfig(hService, nil, 0, pcbBytesNeeded); // Смотрим сколько нужно памяти if GetLastError = ERROR_INSUFFICIENT_BUFFER then begin cbBuffSize := pcbBytesNeeded; GetMem(lpServiceConfig, pcbBytesNeeded); // Берем память try // Получаем расширенную информацию по сервису if QueryServiceConfig(hService, lpServiceConfig, cbBuffSize, pcbBytesNeeded) then Result := lpServiceConfig; // зависимости finally FreeMem(lpServiceConfig); // Завершающее освобождение памяти end; end; finally CloseServiceHandle(hService); end; // close service control manager handle CloseServiceHandle(schm); end; end; procedure FillDependenciesTree(var tv: TTreeView; lpQueryServiceConfig: PQueryServiceConfig; const pn: TTreeNode; sMachine: string); var Dependencies: TStringList; I: Integer; childnode: TTreeNode; data: PChar; DepenServConfig: PQueryServiceConfig; begin data := lpQueryServiceConfig^.lpDependencies; if (pn = nil) and (data = '') then tv.Items.AddChildFirst(nil, 'No dependencies founded'); Dependencies := TStringList.Create; Dependencies.Clear; try while (Data <> nil) and (Data^ <> #0) do begin Dependencies.Add(Data); Data := StrEnd(Data); Inc(Data); end; Dependencies.Sort; for I := 0 to Dependencies.Count - 1 do begin DepenServConfig := GetDependenceService(sMachine, Dependencies[i]); childnode := tv.Items.AddChild(pn, ServiceGetDisplayName(sMachine, Dependencies[i]) + ' (' + Dependencies[i] + ')'); // childnode.ImageIndex := GetImageIndex(DepenServConfig^.dwServiceType, 0, 1, 2); // childnode.SelectedIndex := childnode.ImageIndex; FillDependenciesTree(tv, DepenServConfig, childnode, sMachine); // зависимости end; finally FreeAndNil(Dependencies); end; end; |
Сообщ.
#7
,
|
|
|
Цитата VahaC @ Вот процедура которая заполняет TTreeView "зависимостями" Огромное спасибо, но у меня пока нет времени, в идеале хочу сделать окно зависимостей и в DT, и в RT. Очень ценное сообщение, особенно его вторая часть . Еще раз спасибо . |