您好我在这里有这段代码:
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。
有什么想法吗?
**编辑:我想这样做,这样我就可以避免每次出现一个新线程时都需要重新挂起这个过程。
答案 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编写者来了解这样做的原因。