Как перенаправить доступ в реестр dll, загруженной моей программой - PullRequest
4 голосов
/ 18 июня 2010

У меня есть dll, который я загружаю в свою программу, которая читает и записывает свои настройки в реестр (hkcu). Моя программа изменяет эти настройки до загрузки библиотеки DLL, поэтому она использует настройки, которые моя программа хочет использовать, и это прекрасно работает.

К сожалению, мне нужно запустить несколько экземпляров моей программы с различными настройками для DLL. Теперь подход, который я использовал до сих пор, больше не работает надежно, потому что один экземпляр программы может перезаписать настройки, которые другой экземпляр только что написал, прежде чем DLL сможет их прочитать.

У меня нет источника DLL, о котором идет речь, и я не могу попросить программиста, написавшего его, изменить его.

Одна из моих идей заключалась в том, чтобы подключить функции доступа к реестру и перенаправить их в другую ветку реестра, которая специфична для экземпляра моей программы (например, использовать идентификатор процесса как часть пути). Я думаю, что это должно сработать, но, возможно, у вас есть другой / более элегантный.

В случае, если это имеет значение: я использую Delphi 2007 для своей программы, dll, вероятно, написан на C или C ++.

Ответы [ 3 ]

4 голосов
/ 05 октября 2010

В качестве альтернативы перехвату API, возможно, вы могли бы использовать RegOverridePredefKey API.

3 голосов
/ 18 июня 2010

Вместо перехвата доступа к реестру для 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;

Чтобы освободить мьютекс, вы должны использовать API ReleaseMutex, а для приобретения созданного мьютекса вы должны использовать API OpenMutex.

Для 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 голосов
/ 08 октября 2010

грязный метод: откройте dll в гекседиторе и измените / измените путь реестра от исходного куста до любого другого, который вы хотите использовать или у которого есть правильные настройки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...