2010-06-18 33 views
4

加载的DLL我有,我在我的程序读取和注册表(HKCU)写入其设置加载DLL的注册表访问。我的程序在加载dll之前更改这些设置,以便它使用我的程序希望它使用的设置,这很好。如何通过重定向我的程序

不幸的是我需要用dll的不同设置运行我的程序的几个实例。现在我迄今使用的方法不再可靠,因为程序的一个实例可能会覆盖另一个实例在dll有机会读取它们之前写入的设置。

我没有得到有关该dll的来源,我不能要求它是谁写来改变它的程序员。

我有一个想法,就是勾注册表访问功能,将其重定向到注册表的一个不同的分支是专门针对我的方案的情况下(例如使用进程ID作为路径的一部分)。我认为这应该可行,但也许你有不同/更优雅。

如果它的事项:我使用德尔福2007年我的程序,该DLL可能是用C或C++。

回答

4

作为替代API钩子,也许你可以使用RegOverridePredefKey API。

+0

这是一个有趣的想法。我会给它一个旋风。谢谢。 – dummzeuch 2010-10-08 13:45:40

3

相反挂钩DLL的注册表访问,你可以使用进程间的锁定机制,将值写入注册表自己的应用程序。这个想法是,instance1获得的锁只有在它的dll“instance”读取了值之后才会释放,这样instance2在启动时才会获得锁,直到instance1完成。你需要一个锁定机制,在这个过程中工作。例如互斥体。


要创建互斥:

procedure CreateMutexes(const MutexName: string); 
    //Creates the two mutexes checked for by the installer/uninstaller to see if 
    //the program is still running. 
    //One of the mutexes is created in the global name space (which makes it 
    //possible to access the mutex across user sessions in Windows XP); the other 
    //is created in the session name space (because versions of Windows NT prior 
    //to 4.0 TSE don't have a global name space and don't support the 'Global\' 
    //prefix). 
const 
    SECURITY_DESCRIPTOR_REVISION = 1; // Win32 constant not defined in Delphi 3 
var 
    SecurityDesc: TSecurityDescriptor; 
    SecurityAttr: TSecurityAttributes; 
begin 
    // By default on Windows NT, created mutexes are accessible only by the user 
    // running the process. We need our mutexes to be accessible to all users, so 
    // that the mutex detection can work across user sessions in Windows XP. To 
    // do this we use a security descriptor with a null DACL. 
    InitializeSecurityDescriptor(@SecurityDesc, SECURITY_DESCRIPTOR_REVISION); 
    SetSecurityDescriptorDacl(@SecurityDesc, True, nil, False); 
    SecurityAttr.nLength := SizeOf(SecurityAttr); 
    SecurityAttr.lpSecurityDescriptor := @SecurityDesc; 
    SecurityAttr.bInheritHandle := False; 
    CreateMutex(@SecurityAttr, False, PChar(MutexName)); 
    CreateMutex(@SecurityAttr, False, PChar('Global\' + MutexName)); 
end; 

要释放一个互斥体,你会使用ReleaseMutex API和获取创建的互斥,你应该使用OpenMutex API。

对于CreateMutex见:http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx

对于OpenMutex看到:http://msdn.microsoft.com/en-us/library/ms684315(v=VS.85).aspx

对于ReleaseMutex看到:http://msdn.microsoft.com/en-us/library/ms685066(v=VS.85).aspx

+0

全局互斥是否需要管理员权限和/或提升? – Remko 2010-06-18 08:30:43

+0

不要这样想。在我的一个应用程序中使用它而不需要仰角,它不会呻吟需要提升。当然,我是我系统中的管理员,但由于它被用作进程间锁定机制,并且经常用作防止应用程序启动两次的手段,所以我不明白为什么全局互斥体需要使用amdin特权时。 – 2010-06-18 10:15:18

+1

@Marjan:感谢您的建议,但不幸的是,这并不能解决我的问题,因为我不知道dll何时可以访问这些设置。它可能是当它正在被加载,或者它被调用时或者在其他时间。 (另外Delphi在单元SyncObjs中有一个TMutex类,这会使你使用Windows API更方便一些,就像在你的例子中一样。) – dummzeuch 2010-07-08 07:36:50

0

肮脏的方法:在16进制软件打开该DLL和改变/更改您要使用或有你正确设置任何其他从原来的蜂巢注册表路径。