![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
От какого пользователя запущено приложение.
Enzain © (2015-01-06 12:44:00)Всех приветствую.
Несколько лет не вспоминал про дельфи, и вот ... случилось чудо.
Собственно задача:
Есть сервис, который мониторит БД, в определенный момент нужно закрыть все приложения 1с77, кроме экземпляров запущщеных от определенного пользователя. Пробежать по процессам и закрыть все 1ски я в общем-то смог. Теперь вопроса осталось два
1. Как узнать имя пользователя, под которым выполняется приложение.
2. как прочитать заголовок окна 1с. (потому как если у пользователя не та база доступ к которой надо закрыть - то и закрывать приложение не надо)
3. Так как давно не пользовался дельфей, то не помню в упор (а с учетом смены версий уже и не знаю) - была утилита позволяющая узнавать классы и хендлы запущеных форм и кнопок (в лаунчере 1с задизаблить кнопку "добавить")
ПС: да, нужна выгонялка из 1с, из того что есть - всё не то.
enzain (2015-01-07 14:11:00) [1]В общем эту тему можно закрыть.
Другие вопросы в других темах озвучу... а то всё в одном не очень хорошо.
enzain (2015-01-06 21:22:00) [2]Обманул.
В 10 - не все пробегает окна ... а может так оказаться что не окна пробегает то ...
Блин, что-то я запутался.... вредно возвращаться к старому через столько лет ... :(
enzain (2015-01-06 20:59:00) [3]Так вот ...
Первоначально это было просто нахождение приложений всех запущенных.
Потом прикрутилось определение под каким пользователем запущено.
И только потом уже была попытка прикрутить скажем так, определение заголовка окна приложения которое запущено....
enzain (2015-01-06 20:57:00) [4]По поводу цикла - пока чтобы хоть как то работало.
Дальше уже просмотр на костыли ... так как я уже много лет вообще дельфей не касался - вообще не уверен что в ней адекват сейчас ...
enzain (2015-01-06 20:56:00) [5]При том что так:
function AddCaption(Handle:HWND;ShowCmd:integer):bool;stdcall;
var s:PChar;
begin
GetMem(s,255);
GetWindowText(Handle,s,255);
if length (s) >0 then form1.ListBox1.Items.Add(s);
FreeMem(s);
result:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
EnumWindows(@AddCaption,0);
end;
список заголовков окон вроде как выводит ... хм..
Rouse_ (2015-01-06 20:49:00) [6]Ой, пардон, так у тебя CreateToolhelp32Snapshot еще и в цикле?!!
Ну... тут уж сам себе злой буратин.
Rouse_ (2015-01-06 20:47:00) [7]Ну беда то у тебя начинается примерно здесь: CreateToolhelp32Snapshot
Я писал в свое время об этом: http://alexander-bagel.blogspot.ru/2012/12/api.html
enzain (2015-01-06 20:41:00) [8]везде что-то подобное:
procedure TForm1.Button1Click(Sender: TObject);
begin
EnumWindows(@EnumProc,0);
end;
procedure findHandl(id:integer;h:hwnd);
var
ssh1, ssh2 : THandle;
pe32 : TProcessEntry32;
me32 : TModuleEntry32;
str:array[0..255]of char;
begin
ssh1 := CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
pe32.dwSize := SizeOf(pe32);
me32.dwSize := SizeOf(me32);
if Process32First(ssh1, pe32) then
repeat
if UpperCase(pe32.szExeFile)=UpperCase('notepad.exe') then begin
ssh2 := CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, pe32.th32ProcessID);
if Module32First(ssh2, me32) then
if me32.th32ProcessID=id then begin
ZeroMemory(@str,sizeof(str));
if (GetWindowText(h, str, 255) > 0) then
form1.Memo1.lines.add(inttostr(h)+' '+str);
end;//if
CloseHandle(ssh2);
end;//if
until not Process32Next(ssh1, pe32);
CloseHandle(ssh1);
end;
function EnumProc(Wd: HWnd; Param: Integer): Boolean;stdcall;
var ProcessId:integer;
begin
GetWindowThreadProcessId(wd, @ProcessId);
findHandl(ProcessId,wd);
result:=true;
end;
Таких вариантов много, но код примерно один, разве что может имена переменных отличаются.
Ну так то, не беда была б, если бы оно результат давало, но оно ж не дает собака серая ... :)
Rouse_ (2015-01-06 19:25:00) [9]15 секунд?!!! Беда :)
Дай ссылку на все эти медленные примеры, посмотрю что в них не так
enzain (2015-01-06 19:02:00) [10]Да я б и рад ... но все примеры которые нахожу - вешают приложение секунд на 15, и ничего ... что странно ... кстати и имена пользователей на терминале для приложений получить не смог ... из сервиса, запущенного под системой - ради бога ... а вот простому смертному админу - не дает ...
Rouse_ (2015-01-06 17:53:00) [11]Ну... Просто все окна перебери и найди нужные, findчетотам апишка называтся
enzain (2015-01-06 16:18:00) [12]Так.... во первых, то что будет дебаг приложением для файла 1с в коде имеет такое:
var
hw, hwb : HWND;
begin
hw := FindWindow(nil, 'Запуск 1С:Предприятия');
if hw0 then
Begin
hwb := FindWindowEx(hw,0, nil, '&Добавить');
if hwb 0 then showwindow(hwb,sw_hide);
hwb := FindWindowEx(hw,0, nil, '&Изменить');
if hwb 0 then showwindow(hwb,sw_hide);
hwb := FindWindowEx(hw,0, nil, '&Удалить');
if hwb 0 then showwindow(hwb,sw_hide);
End;
Тут все понятно ... запустить но убрать возможность добавления редактирования и удаления баз из загрузчика 1с ....
Как узнать хендл процесса про процессид - я вроде тоже нашел ... так же как и понять от кого запущено приложение ....
теперь не могу вкурить как говорится - каким макаром найти в приложении (по хендлу) все формы ныне открытые, и прочитать их заголовки .... вот хоть ты убейся не могу понять ...
Rouse_ (2015-01-06 13:05:00) [13]
> 1. Как узнать имя пользователя, под которым выполняется
> приложение.
Сначала: http://msdn.microsoft.com/ru-ru/library/windows/desktop/aa379295(v=vs.85).aspx
Потом: http://msdn.microsoft.com/ru-ru/library/windows/desktop/aa446671(v=vs.85).aspx с флагом TokenUser
Как пример: http://www.kansoftware.ru/?tid=5393
> 2. как прочитать заголовок окна 1с. (потому как если у пользователя
> не та база доступ к которой надо закрыть - то и закрывать
> приложение не надо)
> 3. Так как давно не пользовался дельфей, то не помню в упор
> (а с учетом смены версий уже и не знаю) - была утилита позволяющая
> узнавать классы и хендлы запущеных форм и кнопок (в лаунчере
> 1с задизаблить кнопку "добавить")
>
Оно?
http://rouse.drkb.ru/winapi.php#wndinfo
enzain (2015-01-06 12:49:00) [14]Да, извиняюсь .. забыл вставить код которым пробегаю по процессам ....
function KillTask(ExeFileName: string): integer;
const
PROCESS_TERMINATE=$0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot
(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle,
FProcessEntry32);
while integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
UpperCase(ExeFileName))
or (UpperCase(FProcessEntry32.szExeFile) =
UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(OpenProcess(
PROCESS_TERMINATE, BOOL(0),
FProcessEntry32.th32ProcessID), 0));
ContinueLoop := Process32Next(FSnapshotHandle,
FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;