![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как обратиться к свойству объекта [D7, Win2k, WinXP]
pavel_guzhanov © (2005-01-25 14:14:00)Вопрос такой: У Объекта имеется множество свойств. Мне нужно получить значение только одного свойства, например свойства "name". Приходится в цикле перебирать все свойства, и, дойдя до свойства "name" присвоить его значение какой- либо переменной. А можно ли обратиться к свойству непосредственно по его имени, не перебирая все остальные? И если можно, то как?
pavel_guzhanov (2005-01-26 11:15:00) [1]
> SProp := SObject.Properties_.Item[Name];
Вот то, что мне было нужно!!! Спасибо всем, кто помогал!!!
REA (2005-01-26 10:57:00) [2]SProp := SObject.Properties_.Item[Name];
насчет синтаксиса не уверен, но смысл такой.
Оригинал из MSDN на VB:
wbemCimtypeString = 8
Set objSWbemService = GetObject("Winmgmts:root\default")
Set objClass = objSWbemService.Get()
objClass.Path_.Class = "NewClass"
' Add a property
objClass.Properties_.add "PropertyName", wbemCimtypeString ' String property
' Make the property a key property
objClass.Properties_("PropertyName").Qualifiers_.add "key", true
' Write the new class to the root\default namespace in the repository
Set objClassPath = objClass.Put_
WScript.Echo objClassPath.Path
'Create an instance of the new class using SWbemObject.SpawnInstance
Set objNewInst = GetObject("Winmgmts:root\default:NewClass").Spawninstance_
objNewInst.PropertyName = "My Instance"
' Write the instance into the repository
Set objInstancePath = objNewInst.Put_
WScript.Echo objInstancePath.Path
pavel_guzhanov (2005-01-26 10:30:00) [3]даааа... Как то у меня код отформатировался хитро... Извиняюсь. Это я не специально...
pavel_guzhanov (2005-01-26 10:28:00) [4]
function GetInfo(Service_:ISWbemServices; Cl:String; Name:Str2):String;
var SProp:ISWbemProperty;
PropEnum:IEnumVariant;
SObject:ISWbemObject;
ObjectSet:ISWbemObjectSet;
PropSet:ISWbemPropertySet;
TempObj:OleVariant;
Value:Cardinal;
begin
try SObject:= Service_.Get(Cl, wbemFlagUseAmendedQualifiers, nil);
ObjectSet:= SObject.Instances_(0,nil);
Enum:= (ObjectSet._NewEnum) as IEnumVariant;
Enum.Next(1, TempObj, Value);
SObject:= IUnknown(TempObj) as SWBemObject;
PropSet := SObject.Properties_;
PropEnum:= (PropSet._NewEnum) as IEnumVariant;
except Abort; end;
Ищем нужное свойство (параметр name)
try
while (PropEnum.Next(1, TempObj, Value) = S_OK) do
begin SProp:= IUnknown(TempObj) as SWBemProperty;
if (SProp.Get_Value <> null) then
begin if SProp.Name = Name then
begin
Result:=Trim(SProp.Get_Value);
break;
end; end;
end;
except Abort; end; end;
//==============================================================
procedure TInfo.Execute;
var
Enum:IEnumVariant;
CPU:String[50];
Service:ISWbemServices;
begin
Service:= MainForm.SWbemLocator1.ConnectServer(CompName, 'root\CIMV2', MainForm.EUser.Text, MainForm.MEPassword.Text, '', '', 0, nil);
// процессор
try
CPU:=GetInfo(Service, 'Win32_Processor', 'Name');
except
continue;
end;
Это практически полный код определения названия процессора на компьютере с именем CompName. В функции GetInfo находится Объект 'Name' класса 'Win32_Processor' в цикле, перебором всех объектов этого класса. Этот цикл съедает много времении и памяти. Я же хочу сразу, без цикла, обратиться к объекту 'Name' этого класса, и прочитать его значение. Дело в том, что я определяю не только процессор, а еще много различных устройств, и компьютеров у меня в сети около 200, так что программа работает очень долго, и съедает много памяти. Поэтому я и хочу уйти от этих циклов.
REA (2005-01-26 10:06:00) [5]Приведи кода побольше, а то так можно долго спорить. И укажи что тебе надо и зачем.
pavel_guzhanov (2005-01-26 09:55:00) [6]И еще, вдогонку.. Как мне увязать эту переменную X с компьютером, к которому я подключаюсь? Насколько я понимаю, в моем коде (хотя он практически весьне мой, а взятый из статьи) связь SProp с компьютером идет через TempObj.
pavel_guzhanov (2005-01-26 09:42:00) [7]Правильно ли я понял?
Мне надо объявить переменную X:ISWbemPropertySet, а SProp:=X.Item('Name', 0)? А после этого получить уже SProp.Get_Value?
Или я не так понял? Если не так, то объясните пожалуйста поподробнее, ибо а хелпе я ничего похожего не нашел...
Digitman (2005-01-26 08:58:00) [8]
> pavel_guzhanov (26.01.05 08:45) [22]
видишь ли, Набережных С. в [15] дает верный совет..
обращение к св-ву SWbemPropertySet.Item, принимающему параметром стр.значение имени объекта, точно так же вызывает к выполнению внутренний (скрытый) цикл перебора объектов, входящих в список.
но в этом случае накл.расходы по интерфейсным преобразованиям (IUnknown(TempObj) as SWBemProperty) сводятся к минимуму, что явно и благотворно влияет на сквозную производительность твоего алгоритма
pavel_guzhanov (2005-01-26 08:45:00) [9]
> Дык трудновато объяснить дорогу, если не понятно, куда ему
> нужно:)
А что непонятно? Выложить больший кусок кода, или что-то объяснить поподробнее? Спроси, я отвечу. Дело в том, что, мне кажется, твой совет - это как раз то, что может мне помочь, так что хотелось бы немного прояснить, как этим советом воспользоваться....
Набережных С. (2005-01-25 18:48:00) [10]>Игорь Шевченко © (25.01.05 18:44) [20]
Да я, вероятно, скоро опять исчезну, так что вряд ли стоит:)
Игорь Шевченко (2005-01-25 18:44:00) [11]Набережных С. (25.01.05 18:17) [19]
<offtopic>
Ты б перерегистрировался.
</offtopic>
С уважением,
Набережных С. (2005-01-25 18:17:00) [12]>Digitman © (25.01.05 17:24) [18]
>хотя и в этом случае цикл фигурирует ... только - скрытый ..
Да, конечно, только обмена со службой WMI будет намного меньшь, а это значительно сократит время выполнения. Впрочем, возможно, у него мой совет вообще не применим, без всего кода не берусь судить.
Digitman (2005-01-25 17:24:00) [13]хорошо если SWBemProperty.Name() - дифолт-св-во объекта ..
хотя и в этом случае цикл фигурирует ... только - скрытый ..
внутренняя реализация подобна реал-ции кода
TDataSet.FieldByNames('чего-то там').Value ..
Набережных С. (2005-01-25 17:05:00) [14]>Digitman © (25.01.05 16:54) [16]
Дык трудновато объяснить дорогу, если не понятно, куда ему нужно:) ИМХО, инфы мало. Наугад ткнул пальцем - авось попаду:)
Digitman (2005-01-25 16:54:00) [15]
> Набережных С. (25.01.05 16:49) [15]
въезд через анус - оно, конечно, хорошо).. но ты б хоть объяснил человеку, куда и на ком он туда въезжает ?)
Набережных С. (2005-01-25 16:49:00) [16]У SWbemPropertySet есть метод Item, который принимает строковое имя свойства и возвращает соответствующий объект SWbemProperty. Енумератор не нужен.
Если, конечно, речь об этом.
pavel_guzhanov (2005-01-25 16:31:00) [17]жаль. Из-за циклов очень сильно тормозится программа, и памяти расходуется немеряно.Дело ведь в том, что мне надо обратиться всего к одному, конкретному объекту, с именем 'Name', а все остальные меня не волнуют....
Digitman (2005-01-25 16:22:00) [18]
> pavel_guzhanov (25.01.05 16:16) [12]
а никак.
ты же не можешь знать заранее содержимое списка объектов ..
мало ли какие объекты в каком кол-ве этот список содержит в каждый момент времени !
сейчас в этом списке M объектов, а через час, может статься, в этом списке будет N объектов .. и все они имеют минимум два св-ва : Name и Value
pavel_guzhanov (2005-01-25 16:16:00) [19]
> а когда он, этот объект, станет у тебя текущим ?
Хорошо, тогда вопрос несколько перефразирую: Как сделать этот объект текущим, не пользуясь циклом, и возможно ли это вообще?
Digitman (2005-01-25 16:10:00) [20]
> свойства текущего объекта
вот именно - ТЕКУЩЕГО !
а когда он, этот объект, станет у тебя текущим?
именно тогда когда он им станет в очередной итерации твоего цикла !
у тебя же хренова туча объектов ! и у каждогоиз них есть как минимум 2 св-ва : Имя и Значение
ты же не свойстваперебираешь - ты перебираешь объекты, каждый из которых обладает не менее чем 2-мя св-вами с известными тебе именами !