带静态方法的C#实例类 - 在线程之间使用不同的方法

时间:2010-12-04 00:59:34

标签: c# hook

您好我在这里有这段代码:

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

Memory和Hook都是非静态类,openprocess和Apply都是这些类中的静态方法。

然而,问题是,对于我的Memory或Hook的每个实例,我想要打开一个不同的进程,并应用不同的Hook。

我想做的是:

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

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

但当然我不能这样做,因为这些方法是静态的,并不是每个实例特有的。

我无法更改静态方法,因为这些方法来自一个我无法访问源代码的dll。

有什么想法吗?

**编辑:我想这样做,这样我就可以避免每次出现一个新线程时都需要重新挂起这个过程。

4 个答案:

答案 0 :(得分:1)

似乎你不能通过设计来做到这一点。您正在使用的dll中的类的实现者可能明确地希望避免您尝试实现的功能。

答案 1 :(得分:1)

您可以在不同的AppDomain中加载每个线程,这会为您提供不同的静态方法。

此外,ThreadStaticAttribute可能对您有所帮助。不确定它是否适合你,但请看一下。

Upd:有关使用AppDomains的更多信息。让我们假设您有第3方派对Memory定义如下。 (你不能改变它,它使用内部静态变量)

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

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

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

您可以编写一个包装器,派生自MarshalByRefObject(这很重要):

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

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

因此,如果您创建的MemoryWrap实例不是new个关键字,而是在另一个域中使用AppDomain.CreateInstanceAndUnwrap,那么每个实例都会拥有自己的静态上下文。例如:

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();
    }
}

它会打印出来:

1
2

PS:在那个例子中,我没有为了可读性而做清理(用AppDomain.Unload()和其他东西卸载域)。不要忘记在代码中执行此操作。 +在另一个域中,对象的生命周期有些混乱,但它是下一级别的问题)))

答案 2 :(得分:0)

我不确定我是否完全理解这个问题,但无论如何我都会尽力回答。

您可以定义两个新类:

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);
  }
}

然后在您的代码中,您可以致电:

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

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

答案 3 :(得分:0)

请参阅,如果API编写者这样做,它必须是出于某种原因,您应该咨询您的API编写者,或者他们是否可以在初始级别为您提供一些东西。

但是为了规避您的情况,您可以使用上面提供的The_Smallest方法。

或者您可以使用反射,如下所示

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

但我不相信,你应该这样做,你首先打电话给API编写者来了解这样做的原因。