Задача такова:
Через OpenProcess запускаю задачу N. Устанавливаю приоритет для нее и ее
потока. Мне нужно получить NORMAL_PRIORITY_CLASS и THREAD_PRIORITY_LOW, и я его
получаю. Процесс N запускает процесс N1. Повлиять на параметры запуска я не в
силах.
Требуется установит приоритеты для процесса N1 такиеже как и для N.
Так надо для того что N1 местами грузит машину на 100% и довольно длительное
время, а при приоритете IDLE и большой загрузке проца другими задачами он может
вылететь, видно из-за особенностей стыковки с N.
Если есть другой способ установить ему BELOW_NORMAL, буду рад.
Процес N1 я получаю
hSnapShotProc:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
hSnapShotThrd:=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
IsProc:=Process32First(hSnapShotProc,ProcEntry);
while IsProc do begin
ProcNameExe:=ProcEntry.szExeFile;
if (pos('.......',ProcNameExe)>0) then Begin
//Тут я имею возможность SetPriorityClass(hProc,...IDLE_PRIORITY_CLASS);
//Hо это для него слишком жестоко
ProcID:=ProcEntry.th32ProcessID;
IsThrd:=Thread32First(hSnapShotThrd,ThrdEntry);
while IsThrd do begin
if ThrdEntry.th32OwnerProcessID=ProcID then begin
//Вот тут мне нужно установит приоритет потока
//теоритечески можно //испоьзоватьSetThreadPriority(hThrd,THREAD_PRIORITY_LOW);
//но для нее нужно HandleThread, а я имею только ThreadID
end;
IsThrd:=Thread32Next(hSnapShotThrd,ThrdEntry);
end;
end;
IsProc:=Process32Next(hSnapShotProc,ProcEntry);
end;
Closehandle(hSnapShotProc);
Closehandle(hSnapShotThrd);
За сим удаляюсь, Viacheslav.
... Качество цикуты обычно проверяют на Сократах.
VJ> нужно HandleThread, а я имею только ThreadID
OpenThread NT5+
NtOpenThread NT4
_>а что с 9x ?
function OpenThread(fdwAccess: DWord; fInherit: LongBool;
dwThreadId: DWord):THandle;
asm
mov eax, dwThreadId
xor eax, dwObs
push eax
push fInherit
push fdwAccess
call pOpenProcess
mov Result, eax
end;
где
pOpenProcess := Pointer(DWord(GetProcAddress(GetModuleHandle ('kernel32');,
'OpenProcess' )) + $24);
а dwObs можно (95,98) получить так (by Pavel Ovsyannikov)
call GetProcessHeap // eax нам не нужен, а вот в ecx - ProcessDB
call GetCurrentProcessID // eax=ProcessID=ProcessDB XOR Obfuscator
xor eax,ecx // eax=Obfuscator
--
С уважением, LVT.
23 OCT 04 10:37, Leonid Troyanovsky -> Viacheslav Jeriomin:
VJ>> нужно HandleThread, а я имею только ThreadID
LT> OpenThread NT5+
То что доктор прописал.
LT> NtOpenThread NT4
_>> а что с 9x ?
LT> function OpenThread(fdwAccess: DWord; fInherit: LongBool;dwThreadId:
LT> DWord):THandle;
LT> asm
...
LT> end;
Вначале не совсем понял ответ, начал копать в куске кода который указан для 9х,
хотя у меня w2k. Т.к. я программер любитель, то не мог предположить что
функция OpenThread в Дельфи7-windows.pas и справке Win32 Developer References
не указана, но в kernel32 присутствует.
Догадываюсь что ее описание можно прочитать в MSDN, но такой возможности не
имею. Т.к. не знаю параметров, пишу так:
interface
Procedure My;
function OpenThread(dwThreadId: DWORD): THandle; stdcall; external kernel32
name 'OpenThread';
implementation
procedure My;
begin
.....
while IsThrd do begin
if ThrdEntry.th32OwnerProcessID=ProcID then begin
hThrd:=OpenThread(PROCESS_ALL_ACCESS,False,ThrdEntry.th32ThreadID);
SetThreadPriority(hThrd,THREAD_PRIORITY_IDLE);
CloseHandle(hThrd);
end;
IsThrd:=Thread32Next(hSnapShotThrd,ThrdEntry);
end;
.....
end;
но hThrd я получаю 0. Какие параметры у этой функции, или на какие грабли я еще
наступаю.
За сим удаляюсь, Viacheslav.
... За два дня до вабоpов яблоки не есть!
VJ> Вначале не совсем понял ответ, начал копать в куске кода который указан
VJ> для 9х, хотя у меня w2k. Т.к. я программер любитель, то не мог
VJ> предположить что функция OpenThread в Дельфи7-windows.pas и справке Win32
VJ> Developer References не указана, но в kernel32 присутствует.
VJ> Догадываюсь что ее описание можно прочитать в MSDN, но такой возможности
VJ> не имею. Т.к. не знаю параметров, пишу так:
VJ> function OpenThread(dwThreadId: DWORD): THandle; stdcall; external
VJ> kernel32 name 'OpenThread';
Здесь, за исключением ": THandle; stdcall", много неточностей.
From MSDN:
OpenThread
The OpenThread function opens an existing thread object.
HANDLE OpenThread(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwThreadId
);
Parameters
dwDesiredAccess
[in] Access to the thread object. This access right is checked against any
security descriptor for the thread. This parameter can be one or more of the
thread access rights.
bInheritHandle
[in] If this parameter is TRUE, the new process inherits the handle. If the
parameter is FALSE, the handle is not inherited.
dwThreadId
[in] Identifier of the thread to be opened.
Return Values
If the function succeeds, the return value is an open handle to the specified
process.
If the function fails, the return value is NULL. To get extended error
information, call GetLastError.
Remarks
The handle returned by OpenThread can be used in any function that requires a
handle to a thread, such as the wait functions, provided you requested the
appropriate access rights. The handle is granted access to the thread object
only to the extent it was specified in the dwDesiredAccess parameter.
When you are finished with the handle, be sure to close it by using the
CloseHandle function.
Requirements
Client: Requires Windows XP, Windows 2000 Professional, or Windows Me.
Server: Requires Windows Server 2003 or Windows 2000 Server.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.
VJ> hThrd:=OpenThread(PROCESS_ALL_ACCESS,False,ThrdEntry.th32Thread
Вот здесь параметры уже ближе к действительности.
VJ> но hThrd я получаю 0. Какие параметры у этой функции, или на какие грабли
VJ> я еще наступаю.
call GetLastError?
--
С уважением, LVT.
26 OCT 04 21:20, Leonid Troyanovsky -> Viacheslav Jeriomin:
VJ>> Вначале не совсем понял ответ, начал копать в куске кода который
VJ>> указан для 9х, хотя у меня w2k. Т.к. я программер любитель, то
VJ>> не мог предположить что функция OpenThread в Дельфи7-windows.pas
VJ>> и справке Win32 Developer References не указана, но в kernel32
VJ>> присутствует. Догадываюсь что ее описание можно прочитать в MSDN,
VJ>> но такой возможности не имею. Т.к. не знаю параметров, пишу так:
Переписал так:
Procedure My;
function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL;
dwProcessId: DWORD): THandle; stdcall;
implementation
function OpenThread; external kernel32 name 'OpenThread';
procedure My;
begin
...........
IsThrd:=Thread32First(hSnapShotThrd,ThrdEntry);
while IsThrd do begin
if ThrdEntry.th32OwnerProcessID=ProcID then begin
hThrd:=OpenThread(PROCESS_ALL_ACCESS,FALSE,ThrdEntry.th32ThreadID);
if hThrd = 0 then
Log( SysErrorMessage(GetLastError) );
SetThreadPriority(hThrd,THREAD_PRIORITY_IDLE);
CloseHandle(hThrd);
end;
IsThrd:=Thread32Next(hSnapShotThrd,ThrdEntry);
end;
............
end;
LT> Parameters
LT> dwDesiredAccess
LT> [in] Access to the thread object. This access right is checked against
LT> any security descriptor for the thread. This parameter can be one or
LT> more of the thread access rights.
Ошибку пишет: 5 (Отказано в доступе).
Какие значения может принимать этот параметр, всетаки PROCESS_ALL_ACCESS для
потока несовсем правильно.
LT> Requirements
LT> Library: Use Kernel32.lib.
А kernel32.dll не подойдет?
За сим удаляюсь, Viacheslav.
... Помылся, надел всё чистое и... отдал себя в руки Правосудия.
LT>> Parameters
LT>> dwDesiredAccess
LT>> [in] Access to the thread object. This access right is checked against
LT>> any security descriptor for the thread. This parameter can be one or
LT>> more of the thread access rights.
VJ> Ошибку пишет: 5 (Отказано в доступе).
Видимо, не хватает прав ;)
VJ> Какие значения может принимать этот параметр, всетаки PROCESS_ALL_ACCESS
VJ> для потока несовсем правильно.
Platform SDK: DLLs, Processes, and Threads
Thread Security and Access Rights
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/t
hread_security_and_access_rights.asp
From JwaWinnt.pas available from http://delphi-jedi.org
(Win32 API Package in the API Library section):
THREAD_TERMINATE = ($0001);
{$EXTERNALSYM THREAD_TERMINATE}
THREAD_SUSPEND_RESUME = ($0002);
{$EXTERNALSYM THREAD_SUSPEND_RESUME}
THREAD_GET_CONTEXT = ($0008);
{$EXTERNALSYM THREAD_GET_CONTEXT}
THREAD_SET_CONTEXT = ($0010);
{$EXTERNALSYM THREAD_SET_CONTEXT}
THREAD_SET_INFORMATION = ($0020);
{$EXTERNALSYM THREAD_SET_INFORMATION}
THREAD_QUERY_INFORMATION = ($0040);
{$EXTERNALSYM THREAD_QUERY_INFORMATION}
THREAD_SET_THREAD_TOKEN = ($0080);
{$EXTERNALSYM THREAD_SET_THREAD_TOKEN}
THREAD_IMPERSONATE = ($0100);
{$EXTERNALSYM THREAD_IMPERSONATE}
THREAD_DIRECT_IMPERSONATION = ($0200);
{$EXTERNALSYM THREAD_DIRECT_IMPERSONATION}
THREAD_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $3FF);
{$EXTERNALSYM THREAD_ALL_ACCESS}
SYNCHRONIZE = ($00100000);
{$EXTERNALSYM SYNCHRONIZE}
LT>> Library: Use Kernel32.lib.
VJ> А kernel32.dll не подойдет?
Она и есть.
--
С уважением, LVT
29 OCT 04 13:50, Leonid Troyanovsky -> Viacheslav Jeriomin:
LT>>> dwDesiredAccess
LT>>> [in] Access to the thread object.
VJ>> Ошибку пишет: 5 (Отказано в доступе).
LT> Видимо, не хватает прав ;)
hThrd:=OpenThread(THREAD_ALL_ACCESS,FALSE,ThrdEntry.th32ThreadID);
SetThreadPriority(hThrd,THREAD_PRIORITY_BELOW_NORMAL);
Большое спасибо, все работает, на все хватает прав.
Столкнулся также еще с одной интересной вещью. Существует программа TaskInfo
2002, там можно посмотреть приоритет, и установить его.
Так вот, она может установить приоритет процесса Below Normal, при этом
указывает приоритет BNorm, а для нитей 6/6.
Есть процессы, например "Приложение служб и контроллеров" для которых приоритет
указан Norm+1, для нитей 9/9.
Для моего процесса указывается _Norm_, нити 7/7.
Отсюда вопрос, как она может менять приоритет на Below Normal, и почему для
моего процесса она не пишет Norm-1.
Значит в Винде вообще, и в Delphi в частности может существовать другой способ
установки приоритета процесса, кроме как с ограниченными константами
HIGH_PRIORITY_CLASS
IDLE_PRIORITY_CLASS
NORMAL_PRIORITY_CLASS
REALTIME_PRIORITY_CLASS
Хотя все и работает, но хочется знать большего, может существует другой, более
простой, но в тоже время гибкий способ работы с приоритетами.
За сим удаляюсь, Viacheslav.
... Хорошо, что есть тупики: можно остановиться, оглянуться.
VJ> Значит в Винде вообще, и в Delphi в частности может существовать другой
VJ> способ установки приоритета процесса, кроме как с ограниченными
VJ> константами
VJ> HIGH_PRIORITY_CLASS
VJ> IDLE_PRIORITY_CLASS
VJ> NORMAL_PRIORITY_CLASS
VJ> REALTIME_PRIORITY_CLASS
Конечно. И самих констант больше
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/s
etpriorityclass.asp
Priority Meaning
ABOVE_NORMAL_PRIORITY_CLASS Process that has priority above
NORMAL_PRIORITY_CLASS but below HIGH_PRIORITY_CLASS.
Windows NT and Windows Me/98/95: This value is not supported.
BELOW_NORMAL_PRIORITY_CLASS Process that has priority above
IDLE_PRIORITY_CLASS but below NORMAL_PRIORITY_CLASS.
Windows NT and Windows Me/98/95: This value is not supported.
HIGH_PRIORITY_CLASS Process that performs time-critical tasks that must be
executed immediately. The threads of the process preempt the threads of normal
or idle priority class processes. An example is the Task List, which must
respond quickly when called by the user, regardless of the load on the
operating system. Use extreme care when using the high-priority class, because
a high-priority class application can use nearly all available CPU time.
IDLE_PRIORITY_CLASS Process whose threads run only when the system is idle.
The threads of the process are preempted by the threads of any process running
in a higher priority class. An example is a screen saver. The idle-priority
class is inherited by child processes.
NORMAL_PRIORITY_CLASS Process with no special scheduling needs.
REALTIME_PRIORITY_CLASS Process that has the highest possible priority. The
threads of the process preempt the threads of all other processes, including
operating system processes performing important tasks. For example, a
real-time process that executes for more than a very brief interval can cause
disk caches not to flush or cause the mouse to be unresponsive.
Т.е., комбинируя базовый класс (приоритета процесса) с SetThreadPriority
и достигается необходимая гибкость.
nPriority
[in] Priority value for the thread. This parameter can be one of the following
values.
Priority Meaning
THREAD_PRIORITY_ABOVE_NORMAL Priority 1 point above the priority class.
THREAD_PRIORITY_BELOW_NORMAL Priority 1 point below the priority class.
THREAD_PRIORITY_HIGHEST Priority 2 points above the priority class.
THREAD_PRIORITY_IDLE Base priority of 1 for IDLE_PRIORITY_CLASS,
BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS,
ABOVE_NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base
priority of 16 for REALTIME_PRIORITY_CLASS processes.
THREAD_PRIORITY_LOWEST Priority 2 points below the priority class.
THREAD_PRIORITY_NORMAL Normal priority for the priority class.
THREAD_PRIORITY_TIME_CRITICAL Base priority of 15 for IDLE_PRIORITY_CLASS,
BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS,
ABOVE_NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base
priority of 31 for REALTIME_PRIORITY_CLASS processes.
This parameter can also be -7, -6, -5, -4, -3, 3, 4, 5, or 6. For more
information, see Scheduling Priorities.
VJ> Хотя все и работает, но хочется знать большего, может существует другой,
VJ> более простой, но в тоже время гибкий способ работы с приоритетами.
У Джефри Рихтера, "Windows для профессиналов" оное подробно разжевано.
Кстати, приоритеты могут динамически меняться планировщиком,
в зависимости от состояния процесса - foreground or not.
--
С уважением, LVT