开发者

C# Instance Class with Static Methods - using methods differently between threads

开发者 https://www.devze.com 2023-01-28 23:54 出处:网络
Hello I have this code here: Memory.OpenProcess(Processes[0].Id); Hook.Apply(........); Memory and开发者_StackOverflow社区 Hook are both non-static classes, and openprocess and Apply are both stati

Hello I have this code here:

Memory.OpenProcess(Processes[0].Id);
Hook.Apply(........);

Memory and开发者_StackOverflow社区 Hook are both non-static classes, and openprocess and Apply are both static methods within those classes.

However, the problem is, for each instance of my Memory or Hook, I want to have a different process opened, and a different Hook applied.

What I want to do is:

Memory newMemory = new Memory();
newMemory.OpenProcess(processes[1].Id);

Hook newHook = new Hook();
newHook.Apply(....);

But of course I cannot do this because the methods are static and not particular to each instance.

I cannot change the static methods because these methods are coming from a dll in which I do not have access to the source code.

Any ideas?

**Edit: I want to do this so I can avoid having to rehook the process every time a new thread comes along that is working with a different process.


It seems that you cannot do that by design. The implementor of the classes from the dll you are consuming might have explicitly want to avoid the functionality you are trying to achieve.


You can load each thread in different AppDomain, that would give you different static methods.

Also, ThreadStaticAttribute might be helpful for you. Don't sure if it fits you, but give it a look.

Upd: More info about using AppDomains. Lets assume, that you have 3-rd party class Memory defined as follows. (And you cannot change it, and it uses inner static variables)

// Cannot be changed
public class Memory
{
    static int StaticId;

    public static void OpenProcess(int id)
    {
        StaticId = id;
    }

    public static int GetOpenedId()
    {
        return StaticId;
    }
} 

You can write a wrapper, deriving from MarshalByRefObject (that's important):

class MemoryWrap : MarshalByRefObject
{
    public void OpenProcess(int id)
    {
        Memory.OpenProcess(id);
    }

    public int GetOpenedId()
    {
        return Memory.GetOpenedId();
    }
}

So if you create instances of MemoryWrap not by new keyword, but using AppDomain.CreateInstanceAndUnwrap in another domain, each instance would have it's own static contexts. Example:

class Program
{
    static void Main(string[] args)
    {
        var type = typeof(MemoryWrap);

        var domain1 = AppDomain.CreateDomain("Domain 1");
        var memory1 = (MemoryWrap)domain1.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);

        var domain2 = AppDomain.CreateDomain("Domain 2");
        var memory2 = (MemoryWrap)domain2.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);

        memory1.OpenProcess(1);
        memory2.OpenProcess(2);

        Console.WriteLine(memory1.GetOpenedId());
        Console.WriteLine(memory2.GetOpenedId());

        Console.ReadLine();
    }
}

It would print:

1
2

PS: in that example I didn't do the clean up just for readability (unloading domains with AppDomain.Unload() and other things). Don't forget to do it in you code. + There is some mess with lifetime of objects in another domain, but it is next level of problems)))


I'm not sure I fully understand the question, but I will try to answer anyways.

You could define two new classes:

public class MemoryInstance : Memory
{
  private var m_instanceProcessId;

  public MemoryInstance(var processId) : base()
  {
    m_instanceProcessId = processId;
  }

  public void OpenProcess()
  {
    Memory.OpenProcess(m_instanceProcessId);
  }
}

public class HookInstance: Hook
{
  private var m_hookId;

  public HookInstance(var hookId) : base()
  {
    m_hookId = hookId;
  }

  public void Apply()
  {
    Hook.Apply(m_hookId);
  }
}

Then in your code you could call:

public static void Main(String[] args)
{
  MemoryInstance newMemory = new MemoryInstance(processes[1].Id);
  HookInstance newHook = new HookInstance(hookId);

  newMemory.OpenProcess();
  newHook.Apply();
}


See , if the API writers are doing that it must be for some reason , you should consult your API writers for he reason or if they can provide you something at instamnce level.

BUT for circumvent your situation , you can use the method provided The_Smallest above.

or you can make use of Reflection as shown below

Memory m = Activator.CreateInstance("Your Dll Name", true) , here true stands for the calling of private constructor.

But i am not convinced , you should do it , you first call to the API writer to get the reason of doing this.

0

精彩评论

暂无评论...
验证码 换一张
取 消