Skip to content

Commit

Permalink
Fixed bug on ExecuteStaticMethod method that was not taking the calli…
Browse files Browse the repository at this point in the history
…ng function name. Solved Issue #22. Improved documentation also to reflex the change.
  • Loading branch information
Nicolas authored and Nicolas committed Mar 31, 2020
1 parent c41c698 commit 1c72e3e
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 44 deletions.
19 changes: 14 additions & 5 deletions ORMi.Sample/Models/Process.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@
namespace ORMi.Sample.Models
{
[WMIClass(Name = "Win32_Process", Namespace = "root\\CimV2")]
public class Process : WMIInstance
public class Process
{
public int Handle { get; set; }
public string Name { get; set; }
public int ProcessID { get; set; }

/// <summary>
/// Date the process begins executing.
/// </summary>
public DateTime CreationDate { get; set; }

public dynamic GetOwnerSid()
Expand All @@ -32,6 +28,12 @@ public int AttachDebugger()
{
return WMIMethod.ExecuteMethod<int>(this);
}

public ProcessResult Create(string commandLine, string currentDirectory, string processStartupInformation)
{
ProcessResult res = WMIMethod.ExecuteStaticMethod<ProcessResult>(new { CommandLine = commandLine, CurrentDirectory = currentDirectory, ProcessStartupInformation = processStartupInformation});
return res;
}
}

public class ProcessOwner
Expand All @@ -40,4 +42,11 @@ public class ProcessOwner
public int ReturnValue { get; set; }
public string User { get; set; }
}


public class ProcessResult
{
public int ProcessId { get; set; }
public int ReturnValue { get; set; }
}
}
17 changes: 10 additions & 7 deletions ORMi.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ static void Main(string[] args)
{
WMIHelper helper = new WMIHelper("root\\CimV2");

Process p = new Process();
p.Create("C:/Windows/notepad.exe", null, null);

//List<NetworkAdapterConfiguration> interfaces = helper.Query<NetworkAdapterConfiguration>().ToList();

//Printer printer = helper.QueryFirstOrDefault<Printer>();
Expand Down Expand Up @@ -49,14 +52,14 @@ static void Main(string[] args)

//List<Processor> procesors = helper.Query<Processor>().ToList();

List<Device> devices = helper.Query<Device>().ToList()
.Where(p => (p.Name ?? "")
.Contains("Intel")).ToList();
//List<Device> devices = helper.Query<Device>().ToList()
// .Where(p => (p.Name ?? "")
// .Contains("Intel")).ToList();

foreach (Device d in devices)
{
Console.WriteLine(d.Name);
}
//foreach (Device d in devices)
//{
// Console.WriteLine(d.Name);
//}

//Person person = new Person
//{
Expand Down
4 changes: 2 additions & 2 deletions ORMi/WMIMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public static T ExecuteStaticMethod<T>()
/// <returns></returns>
public static dynamic ExecuteStaticMethod(dynamic parameters)
{
var frame = new StackTrace().GetFrames().Skip(2).First(x => x.GetMethod().DeclaringType.Namespace != "System.Dynamic");
var frame = new StackTrace().GetFrames().Skip(1).First(x => x.GetMethod().DeclaringType.Namespace != "System.Dynamic");

string methodName = frame.GetMethod().Name;

Expand Down Expand Up @@ -236,7 +236,7 @@ public static dynamic ExecuteStaticMethod(dynamic parameters)
/// <returns></returns>
public static T ExecuteStaticMethod<T>(dynamic parameters)
{
var frame = new StackTrace().GetFrames().Skip(2).First(x => x.GetMethod().DeclaringType.Namespace != "System.Dynamic");
var frame = new StackTrace().GetFrames().Skip(1).First(x => x.GetMethod().DeclaringType.Namespace != "System.Dynamic");

string methodName = frame.GetMethod().Name;

Expand Down
79 changes: 49 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,48 +199,67 @@ IMPORTANT: From version 2.0 all classes that have methods declared must inherit

**Static Methods:**

Let's suppose we have a model class that represents an output on a smart card reader. The class will look like this:
One example of static method is `Create()` on `Win32_Process` class. We are going to use it fo this example. Suppose we have the following model:

```C#
[WMIClass("Lnl_ReaderOutput1")]
public class Output : WMIInstance
[WMIClass(Name = "Win32_Process", Namespace = "root\\CimV2")]
public class Process
{
public int PanelID { get; set; }
public int ReaderID { get; set; }
public string Hostname { get; set; }
public int Handle { get; set; }
public string Name { get; set; }
public int ProcessID { get; set; }
public DateTime CreationDate { get; set; }

public dynamic GetOwnerSid()
{
return WMIMethod.ExecuteMethod(this);
}

public ProcessOwner GetOwner()
{
return WMIMethod.ExecuteMethod<ProcessOwner>(this);
}

public int AttachDebugger()
{
return WMIMethod.ExecuteMethod<int>(this);
}

public ProcessResult Create(string commandLine, string currentDirectory, string processStartupInformation)
{
ProcessResult res = WMIMethod.ExecuteStaticMethod<ProcessResult>(new { CommandLine = commandLine, CurrentDirectory = currentDirectory, ProcessStartupInformation = processStartupInformation});
return res;
}
}

public class ProcessOwner
{
public string Domain { get; set; }
public int ReturnValue { get; set; }
public string User { get; set; }
}
```

We want to call a method that `Lnl_ReaderOutput1` has defined as `Activate` with no parameters in it. First, we are going to change a little bit the `WMIClass` attribute that the class has set. We are going to define the default namespace for the class:
```C#
[WMIClass(Name = "Lnl_ReaderOutput1", Namespace = "root\\OnGuard")]
```
Then, we have to add the method:
```C#
public dynamic Activate()
{
return WMIMethod.ExecuteMethod(this);
}
```
There is two things to note on the above code. The first one is that the method name **MUST** be the same than the method defined on the WMI class that we want to work with. The second one is that the method implementation will always be the same

What `WMIMethod.ExecuteMethod(this)` does is to call the static `WMIMethod` class and pass the actual instance so the WMI methods can be called. If the method require parameters being sent, so we can pass them using a anonymous object:
public class ProcessResult
{
public int ProcessId { get; set; }
public int ReturnValue { get; set; }
}
```
You can see that `Process` class has a couple of methods. Some of them are instance methods like `GetOwner` and others like `Create()` are static. As said earlier, *static* means that there is no need for an instance to be created to call the method. Notice that the implementation of `Create()` method is the following:

```C#
public dynamic Activate(int panelID, int readerID)
{
return WMIMethod.ExecuteMethod(this, new { PanelID = panelID, ReaderID = readerID });
}
ProcessResult res = WMIMethod.ExecuteStaticMethod<ProcessResult>(new { CommandLine = commandLine, CurrentDirectory = currentDirectory, ProcessStartupInformation = processStartupInformation});
```
So, finally, on your code you will have a much more cleaner implementation of method working:
As you can see, you call the `ExecuteStaticMethod` method and specify which type of response you are awaiting by setting the \<T> parameter.

So finally, you call the method simply like this:

```C#
List<Output> outputList = helper.Query<Output>().ToList();
WMIHelper helper = new WMIHelper("root\\CimV2");

foreach (Output o in outputList)
{
dynamic d = o.Activate(1, 5);
}
Process p = new Process();
p.Create("C:/Windows/notepad.exe", null, null);
```

**Instance Methods:**
Expand Down

0 comments on commit 1c72e3e

Please sign in to comment.