Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   WMI - Parámetros del tipo array (https://www.clubdelphi.com/foros/showthread.php?t=94873)

elrayo76 14-09-2020 20:06:02

WMI - Parámetros del tipo array
 
Buenas, estoy menejando la clase Win32_Service de WMI. Esta tiene el método Change que tiene varios parámetros, los cuales hay dos que son un array (no son un simple dato como los otros).

Estos parámetros del tipo array no se como se le deben pasar a los objetos de WMI. Los otros los voy cargando en los métodos correspondientes, con los tipos de datos y sus respectivos nombres de parámetros.

¿Habra que recorrer de alguna forma este parámetro tipo array he ir cargando cada uno de los datos que contiene?. Los valores los voy cargando uno por uno en ISWbemProperty, pero este como es array no se si se maneja de la misma forma o no.

He visto el código de los componentes de Neftalí pero no maneja ningun método de los objetos de WMI con parámetros de tipo array

Para que se entienda, este párametro es un array porque es el nombre de todos los servicios que dependen del que se está cambiando y que se deben iniciar luego del principal.

Saludos

Neftali [Germán.Estévez] 15-09-2020 08:47:08

Puedes probar a pasarlos como OleVariant.
Previamente debes convertir el array of string (por ejemplo) en un array de variants.

Para que me entiendas, este código convierte un array de strings en un array de variants (como OleVariant):

Código Delphi [-]
var
  ArrayStrings: array Of string;
  paramArr:OleVariant;
  i:integer;
begin
  ...
  paramArr := VarArrayCreate([0, High(ArrayStrings)], varVariant);
  for i := Low(ArrayStrings) to High(ArrayStrings) do
     paramArr[i] := ArrayStrings[i];
   ...

Este paramArr puedes usarlo como parámetro en el método Change (por ejemplo).

elrayo76 15-09-2020 16:25:26

Neftalí,

Tu dices que asi como se le pasa cada uno de los parámetros a los objetos de WMI tengo que pasar los dos últimos parámetros de "Change", uno a uno?. Pero no los tomará como si cada valor fuera un parámetro distinto?.

A lo emjor pasando el mismo nombre de parámetro y cambiando los valores luego internamente los toma como un array y arma el parámetro.

Algo asi sería lo que tu dices?

Código Delphi [-]
// Objeto ISWbemObject.
Objeto.Properties_.Add('Nombre Parametro', 'Tipo de dato', False, 0);
Objeto.Set_Value('Dato del parametro');  // Este sería del tipo OleVariant.

La primer línea sería siempre la misma y lo único que cambia es cada uno de los valores que le llegan a esa misma propiedad?

Perdón si no me queda muy claro, pero como no existe mucha documentación del lado de Delphi me estoy guiando por lo que tiene Microsoft y armando todo yo. Lo único que rescato y que me ha servido como referencia son los componentes que tu has diseñado y que tienes en tu blog.

Saludos
El Rayo

Neftali [Germán.Estévez] 16-09-2020 08:37:18

Me he perdido un poco.
¿Puedes poner cómo estás haciendo la llamada al método Change?

elrayo76 16-09-2020 15:18:59

Paso el código del método que tengo en mi clase genérico que tengo en mi clase para ejecutar cualquier método de los de WMI.


Código Delphi [-]
var
  objWMIObject:  ISWbemObject;
  objWMIMethod: SWbemMethod;
  objWMIProperty: SWbemProperty;
  objWMIProp: ISWbemProperty;
  objWMInstance: ISWbemObject;
  objWMInParams: ISWbemObject;
  objWMIOutParams: ISWbemObject;
  olePropValue: OleVariant;
  i: Integer;
  strParamName: String;

begin
  // Verifica si el componente está activo. Sale del método si se cuemple la condición.
  objGuard.CheckFalse(aWMIComponent.Active, ERR_CARBON_COMPONENT_ACTIVATED);

  // Instancia de la clase.
  objWMIObject := TWMIUtils.GetClassInstance(aWMIComponent.WMIServices, aInstanceProp, aInstanceValue, aWMIComponent.WMIClass);

  // No se encontró.
  if not Assigned(objWMIObject) then
  begin
    // Preparar el método.
    objWMIMethod := objWMIObject.Methods_.Item(AMethodName, 0);  // Acá es donde recibe el método que tiene que ejecutar.
    objWMInParams := objWMIMethod.InParameters;
    objWMIOutParams := objWMIMethod.OutParameters;

    // ¿Es un parámetro de entrada?.
    if Assigned(objWMInParams) then
    begin
      objWMInParams.Properties_.Get_Count;
      objWMInstance := objWMInParams.SpawnInstance_(0);
      objWMInParams.Properties_.Get_Count;

      // Recorre el array con los nombres de los parámetros.
      for i := 0 to Length(aParamNameArray) - 1 do
      begin
        // Valida el tipo del parámetro entrada/salida.
        if aParamTypeArray[i] = ptIn then
        begin
          // Acá carga los nombres y tipo de datos de los parámetros...

          objWMIProperty := objWMInstance.Properties_.Add(aParamNameArray[i], aParamDataTypeArray[i], False, 0);



          // En este lugar carga los valores de los parámetros...
          // ¿Que pasa si alguno de los parametros a cargar el del tipo ARRAY y no un simple valor?.

          if aParamDataTypeArray[i] = wbemCimtypeObject then
            olePropValue := null
          else
            olePropValue := aParamValueArray[i];

          objWMIProperty.Set_Value(olePropValue);
        end;
      end;
    end;

    objWMIOutParams := objWMIObject.ExecMethod_(AMethodName, objWMInstance, 0, nil);
    strParamName := aParamNameArray[Length(aParamNameArray) - 1];

    objWMIProp := objWMIOutParams.Properties_.Item('ReturnValue', 0);
    VarClear(olePropValue);
    aResult := objWMIProp.Get_Value;

    // Recupera los parámetros de salida.
    if Assigned(objWMIOutParams) then
    begin
      objWMIOutParams.Properties_.Get_Count;
      objWMInstance := objWMIOutParams.SpawnInstance_(0);

      // Recorre el array con los nombres de los parámetros.
      for i := 0 to Length(aParamNameArray) - 1 do
      begin
        // Si es un parámetro de salida.
        if aParamTypeArray[i] = ptOut then
        begin
          objWMIProp := objWMIOutParams.Properties_.Item(aParamNameArray[i], 0);
          VarClear(olePropValue);
          olePropValue := objWMIProp.Get_Value;
          aParamValueArray[i] := olePropValue;
        end;
      end;
    end;
  end;


Más alla de que a este método los parámetro que le llegan son un array, que eso lo manejo bien. Uno de los items de ese array es otro array y es el que no se como se manda a WMI cada uno de esos items.


Espero que se entienda. Cualquier cosa me preguntas.


Saludos

Neftali [Germán.Estévez] 16-09-2020 15:58:32

Lo que te comentaba es que en estas líneas:

Código Delphi [-]
          if aParamDataTypeArray[i] = wbemCimtypeObject then
            olePropValue := null
          else
            olePropValue := aParamValueArray[i];

          objWMIProperty.Set_Value(olePropValue);


que es donde asignas el valor al parámetro de entrada, utilices el código que te puse anteriormente.

En las propiedades de tipos básicos se pasa el valor. Tenemos un array of variant, y pasamos un elemento de ese array (aParamValueArray[i]).
Ese valor lo almacenamos en olePropValue, que es del tipo OleVariant. Al final ese valor será un string, un integer,...

En el caso de los parámetros de tipo array, empiezas con un array de variants (en lugar de un tipo simple) y lo tienes que acabar pasando como un OleVariant. En ese punto entra el procedimiento (o trozo de código) que te puse más arriba. Con eso pasas un array de valores a un OleVariant. con eso ya lo tienes (creo).

Código Delphi [-]
...
var
  ArrayStrings: array Of string;
  paramArr:OleVariant;
  i:integer;
begin
  ...
  paramArr := VarArrayCreate([0, High(ArrayStrings)], varVariant);
  for i := Low(ArrayStrings) to High(ArrayStrings) do
     paramArr[i] := ArrayStrings[i];
   ...
    ...
Es algo que estoy implementando también en GLibWMI.


La franja horaria es GMT +2. Ahora son las 01:47:30.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi