Текущий архив: 2009.05.10;
Скачать: CL | DM;
Вниз
не работает SetThreadDesktop Найти похожие ветки
← →
Kaaa (2009-03-02 15:48) [0]На всех компьютерах работает нормально, кроме одного ноутбука. Программа создает отдельный десктоп, переключается туда и выполняется в режиме на весь экран. Код в проекте стандартный вроде:
if (DetectNT) then
begin
thisdesktop := GetThreadDesktop(GetCurrentThreadId);
Application.Free;
NewDesktop := CreateDesktop( "MyDesctopUNIC, nil, nil, 0,
GENERIC_ALL, nil );
SetThreadDesktop( NewDesktop ) ; // ЗДЕСЬ НЕПОНЯТНОСТЬ
Application := TApplication.Create(nil);
SwitchDesktop( NewDesktop ) ;
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
try
Application.Run;
finally
if NewDesktop <> 0 then
begin
SetThreadDesktop( thisDesktop );
SwitchDesktop( thisDesktop );
CloseDesktop( NewDesktop );
end;
end;
На этом ноутбуке на строке:SetThreadDesktop( NewDesktop ) ;
получается ошибка. Сам SetThreadDesktop возвращает False, GetLastError = 170: "Требуемый ресурс занят".
Визуально поведение такое же - программа запускается, но она отображается на дефолтном десктопе (это на секунду видно при завершении сеанса), а новый десктоп создается, отображается, но он полностью пустой.
Что это вообще может такое быть?! Как понять "ресурс занят", кто занят - десктоп, текущий поток?! Ничего не понимаю...
На ноуте стоит WinXP SP3 pro. Стоит Kaspersky Internet Security... Даже не знаю что еще сказать. Касперского перед запуском отключать пробовали - не помогает. Вообще деинсталировать касперского не могу, ноутбук не мой, человеку вообще это нафиг не сдалось, серьезно и долго экспериментировать не могу, просто так случилось, что выявил данный баг именно на этом ноуте.
Что хоть предположить можно?
← →
sniknik © (2009-03-02 15:56) [1]> SetThreadDesktop( NewDesktop ) ; // ЗДЕСЬ НЕПОНЯТНОСТЬ
действительно непонятность... почему в нее передается хендл десктопа хотя требует она id потока? странно что вообще хоть где то работает.
> Что хоть предположить можно?
глюки в коде как обычно.
← →
clickmaker © (2009-03-02 16:03) [2]> почему в нее передается хендл десктопа хотя требует она
> id потока?
она требует как раз десктоп
однако, function will fail if the calling thread has any windows or hooks on its current desktop (с) MSDN
← →
sniknik © (2009-03-02 16:08) [3]> она требует как раз десктоп
хм.. действительно. повелся на название.
← →
sniknik © (2009-03-02 16:15) [4]вот так должно работать
function NewThread(Parameter: Pointer): Integer; stdcall;
var
hDeskNew, hDeskOld: THandle;
StInfo: TStartupInfo;
PrInfo: TProcessInformation;
begin
hdeskNew:= CreateDesktop("MyDesktop", nil, nil, DF_ALLOWOTHERACCOUNTHOOK, MAXIMUM_ALLOWED, nil);
if hDeskNew <> 0 then begin
hdeskOld:= GetThreadDesktop(GetCurrentThreadId());
SetThreadDesktop(hDeskNew);
SwitchDesktop(hDeskNew);
ZeroMemory(@StInfo, SizeOf(StInfo));
StInfo.cb:= SizeOf(StInfo);
StInfo.lpDesktop:= PChar("MyDesktop");
StInfo.wShowWindow:= SW_SHOW;
if (CreateProcess(nil, "notepad.exe", nil, nil, False, 0, nil, nil, StInfo, PrInfo)) then begin
WaitForSingleObject(PrInfo.hProcess, INFINITE);
CloseHandle(PrInfo.hProcess);
CloseHandle(PrInfo.hThread);
end;
SwitchDesktop(hDeskOld);
SetThreadDesktop(hDeskOld);
CloseDesktop(hDeskNew);
end;
result:= 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var ThreadId: DWORD;
begin
CreateThread(nil, 0, @NewThread, nil, 0, ThreadId);
end;
← →
Anatoly Podgoretsky © (2009-03-02 16:22) [5]> Kaaa (02.03.2009 15:48:00) [0]
Нет проверки на ошибку, а это слишком самоуверено.
← →
Kaaa (2009-03-02 16:45) [6]
> однако, function will fail if the calling thread has any
> windows or hooks on its current desktop (с) MSDN
ну указанный код выполняется в Main функции приложения, что там успело создаться? Только если VCL"овский Application успел создать окно, но ведь делается Application.Free. И то не успевает по-моему, это происходит в Application.Initialize
Да и на большинстве тестируемых компов все отлично работает. Вот только на этом ноуте такая бяка :(
Куда грешить? Кто-то успех поставить хук на поток?! Каким образом? Касперский, другое ПО? Кто встречался с таким?
P.S. Данный код выкладывал в частности Leonid Troyanovsky, это я для тех, кто привык оценивать код не по его содержимому, а по нику отпостившего.
← →
Kaaa (2009-03-02 18:57) [7]Никто не встречался с таким?
Какое-то следящее / троянистое ПО видимо установлено на компе?
← →
sniknik © (2009-03-02 20:57) [8]> Код в проекте стандартный вроде:
а сделай совсем пустой проект с одной формой и без кода (кроме показанного)
> Application := TApplication.Create(nil);
> SwitchDesktop( NewDesktop ) ;
попробуй поменять местами... а для гарантии еще sleep на секунду, две воткнуть перед созданием Application.
проверь код из 4, естественно выполнение нотепада заменить на действия Application, и стартовать не по кнопке, а в основной программе.
???
естественно это для проверок на проблемной машине. главное первое, избавиться от "стандартного вроде" кода, а то оно у тебя может на Application.Run; вылетает, а сообшение выдает в основной десктоп.
← →
sniknik © (2009-03-02 20:58) [9]> естественно выполнение нотепада заменить на действия Application
а можно еще и с ним проверку сделать. не помешает.
← →
Kaaa (2009-03-03 11:35) [10]
> а сделай совсем пустой проект с одной формой и без кода
> (кроме показанного)
так и делал
> попробуй поменять местами... а для гарантии еще sleep на
> секунду, две воткнуть перед созданием Application.
Что-то ты уже второй раз тупишь )) Какой смысл менять эти строчки местами, если ошибка на строке ВЫШЕ:
> SetThreadDesktop( NewDesktop ) ;
> проверь код из 4
честно говоря, не вижу смысла его проверять. А если он заработает даже правильно - что дальше?
Создавать в этом новом потоке объект Application, потом все формы?! VCL компоненты же не потокобезопасные, они ДОЛЖНЫ работать в основном потоке, а не в каком-то дополнительно созданном, согласен?
← →
Kaaa (2009-03-04 12:29) [11]Ни у кого не появились может какие идеи?
← →
Leonid Troyanovsky © (2009-03-04 18:34) [12]
> Kaaa (04.03.09 12:29) [11]
> Ни у кого не появились может какие идеи?
Если некий хук успел зацепиться за наш поток и создал
в хуковой процедуре (скрытое) окно, то (невольно) поток
станет его владельцем и, сл-но, [2].
Проще всего, наверное, проверить путем EnumThreadWindows.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2009-03-04 18:50) [13]
> Leonid Troyanovsky © (04.03.09 18:34) [12]
> в хуковой процедуре (скрытое) окно,
Мда, или (нечаянно) установил хук.
Проверить немного сложней, т.е. запрашивать
список загруженных длл и искать в ем левые.
Как запросить список есть в факе на сайте у АП
(хук для своего приложения, ес-но, не нужен,
только запрос).
--
Regards, LVT.
← →
Leonid Troyanovsky © (2009-03-04 18:56) [14]
> Kaaa (03.03.09 11:35) [10]
> Создавать в этом новом потоке объект Application, потом
> все формы?! VCL компоненты же не потокобезопасные, они ДОЛЖНЫ
> работать в основном потоке, а не в каком-то дополнительно
> созданном, согласен?
By Peter Below:
http://groups.google.com/group/borland.public.delphi.nativeapi/msg/f392e4729c58ce8a
--
Regards, LVT.
← →
Kaaa (2009-03-04 19:20) [15]Про окна обязательно проверю. Список DLL тоже пошустрю (ведь можно с помощью ProcessExplorer?).
Интересно, а к таким последствиям может приводить какое-либо ЛЕГАЛЬНОЕ ПО?
И что в результате, собственно, делать? Раньше просто разворачивал на весь экран приложение. Потом по совету Леонида переписал в виде создания отдельного десктопа... А тут оказывается такие грабли могут быть (
Что касается решения от Peter Below, я так понимаю, он сам признается, что это недокументировано и работает на его конфигурации и тестируемой системе, а за все остальное он не отвечает (((
← →
Leonid Troyanovsky © (2009-03-04 19:40) [16]
> Kaaa (04.03.09 19:20) [15]
> Интересно, а к таким последствиям может приводить какое-
> либо ЛЕГАЛЬНОЕ ПО?
Пуркуа бы не па. Хуки еще не запретили, например, MS следит
так за раскладкой клав. А как создавать в чужом потоке окна
показывал Джеф Рихтер (еще тогда), у него много читателей.
> А тут оказывается такие грабли могут быть (
Грабли - они везде. Видимо, поэтому программисты по уровню
паранойи занимают второе место.
--
Regards, LVT.
← →
clickmaker © (2009-03-04 19:43) [17]> программисты по уровню
> паранойи занимают второе место
хм... а кто первое?
← →
Leonid Troyanovsky © (2009-03-04 19:55) [18]
> Kaaa (04.03.09 19:20) [15]
> И что в результате, собственно, делать?
Как чего? Вырываться на простор своего десктопа,
чужие окна - закрывать, хуки - не пускать (WH_DEBUG)
вплоть до Application.Free, потом, IMHO, уже не догонят.
Пусть разработчики кривого (вред) ПО сами отдуваются.
--
Regards, LVT.
← →
Kaaa (2009-03-04 19:56) [19]Леонид, а чтобы ты в результате делал, если нужно развернуться на полный экран в данном случае?
Пытался бы какими-либо способами (уничтожение хуков, окон или еще чего) все таки развернуться на отдельном десктопе или при отбое от SetThreadDesktop разворачивался бы на текущем?
← →
Leonid Troyanovsky © (2009-03-04 19:57) [20]
> clickmaker © (04.03.09 19:43) [17]
> хм... а кто первое?
Админы, IMHO.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2009-03-04 20:08) [21]
> Kaaa (04.03.09 19:56) [19]
> Пытался бы какими-либо способами (уничтожение хуков, окон
> или еще чего) все таки развернуться на отдельном десктопе
> или при отбое от SetThreadDesktop разворачивался бы на текущем?
Не, это дело принципа, если меня не пустят на мой же десктоп.
Сначала по-хорошему, а не захотят - вплоть до NTSuspendProcess.
Да, окна вторичны, причина - хуки. Хотя, нужна еще инфа.
--
Regards, LVT.
← →
Kaaa (2009-03-05 12:19) [22]
> Да, окна вторичны, причина - хуки. Хотя, нужна еще инфа.
какая?
← →
KSergey © (2009-03-05 12:36) [23]> Kaaa (05.03.09 12:19) [22]
> > Да, окна вторичны, причина - хуки. Хотя, нужна еще инфа.
> какая?
Наверное вот это бы уже пора проделать? времени вагон ушло.
> Kaaa (04.03.09 19:20) [15]
> Про окна обязательно проверю. Список DLL тоже пошустрю
Страницы: 1 вся ветка
Текущий архив: 2009.05.10;
Скачать: CL | DM;
Память: 0.53 MB
Время: 0.015 c