Вызов dll C ++ (неуправляемый код) из службы Windows C # (написано в управляемом коде) - PullRequest
6 голосов
/ 22 января 2011

Я работаю над проектом C ++, в котором есть разные компоненты.Нам нужно запустить приложение в качестве службы Windows.Проект представляет собой неуправляемый код C ++.Я написал службу Windows на C # и dll в стиле C, у которого будет функция для запуска различных компонентов, а другая - для их остановки.DLL имеет два файла, заголовок и файл .cpp: RTSS.h:

namespace PFDS
{
  extern "C" __declspec(dllexport) int runRTS(char*);
}

RTSS.cpp:

using namespace PFDS;
/* ... includes and declarations */
extern "C" __declspec(dllexport) int runRTS(char* service_name)
{
   g_reserved_memory = (char*) malloc(sizeof(char) * RESERVED_MEMORY_SIZE);
   _set_new_handler(memory_depletion_handler);
   // this function is from a C++ .lib which is included in
   // the linker input for the RTSS dll project setting.
   // SetUnhandledExceptionHandler("RTS");       
   return 0;
}

В подклассе ServiceBase службы Windows, яУ меня есть следующее:

[DllImport("RTSSd.dll")]
public static extern int runRTS(string serviceName);

protected override void OnStart(string[] args)
{
  try
  {
    // the bin directory has all dependencies (dlls needed)
    Environment.CurrentDirectory = "D:/work/projects/bin";
    eventLog1.WriteEntry("RTSWinService: Starting " + this.ServiceName);
    int result = runRTS(this.ServiceName);
    eventLog1.WriteEntry("Result of invoking runRTS = " + result);
  }
  catch (Exception e)
  {
    eventLog1.WriteEntry("Exception caught: " + e.ToString());
  }
}

Кроме того, у меня есть консольное тестовое приложение с кодом внутри main, похожим на код внутри OnStart.И приложение, и служба Windows работают без проблем, когда комментируется функция SetUnhandledException.Но когда я раскомментирую эту функцию, консольное приложение Windows работает нормально, но служба Windows выводит следующее исключение:

System.DllNotFoundException: Невозможно загрузить DLL 'RTSSd.dll': указанный модуль могне найден(Исключение из HRESULT: 0x8007007E) в RTSWS.RTSWinService.runRTS (String serviceName) в RTSWS.RTSWinService.OnStart (String [] args) в D: \ work \ project \ ... \ RTSWinService.cs: строка 39

Я читал в некоторых темах на разных форумах, что службы Windows запускаются в C: \ WINDOWS \ System32, и это так, поскольку инициализация DirectoryInfo и печать его полного имени показывают это.Я попытался изменить начальный каталог по умолчанию с помощью Environment.CurrentDirectory = "каталог, в котором находятся исполняемый файл службы Windows и библиотеки DLL", но это не сработало.Я также пытался изменить каталог Process, но и это не удалось.Другие темы приводят к такому выводу текст ссылки , но так ли это на самом деле?Может ли быть что-то попроще?Следует отметить, что функция SetUnhandledException написана на C ++, а не на C, как и многие другие функции, которые мне нужно вызывать.Все необходимые библиотеки находятся рядом с исполняемым файлом сервиса.Ваше мнение очень ценится.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 22 января 2011

Когда что-то работает на консоли, но не как служба, я всегда подозреваю, что права доступа.Убедитесь, что пользователь, от имени которого запущена служба, имеет доступ на чтение / выполнение к d: \ work \ projects \ bin.

Другим предложением является вызов SetDllDirectory, который является более прямым способом сказать, где находятся библиотеки DLL.чем использовать текущий каталог.См. этот SO-поток в пути поиска pinvoke dll

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

1 голос
/ 25 января 2011

Просто хотел обновить эту тему. Оказалось, что проблема была исключительно в моей машине. Один и тот же кодовый набор работал как шарм на другом компьютере, в той же версии Windows (32-битная Windows XP, SP2) На обеих машинах Visual Studio 2008 использовался для создания сервиса. Большое спасибо за все комментарии и ответ. Я ценю это.

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