Есть кусок кода(C#), который работает с dll(C++)
в dll передается массив объектов для инициализации.
Если все это дело работает в консольном приложении, то все норм, но если через win-service,то массивы не инициализируются в dll. Такое ощущение что метод из dll(c++) просто не вызывается.
Вызов сделан через DllImport
Кто-нибудь может разъяснить, в чем косяк?
ps пробовал запускать службу под разными аккаунтами, в том числе и под админом.
M>Если все это дело работает в консольном приложении, то все норм, но если через win-service,то массивы не инициализируются в dll. Такое ощущение что метод из dll(c++) просто не вызывается.
Ну чудес-то не бывает, может быть, действительно не вызывается?
M>Кто-нибудь может разъяснить, в чем косяк?
Код DLL показывай.
JID: x64j@jabber.ru
Re[2]: windows service (C#) dll (c++)
От:
Аноним
Дата:
24.09.09 13:43
Оценка:
Здравствуйте, x64, Вы писали: x64>Ну чудес-то не бывает, может быть, действительно не вызывается? x64>Код DLL показывай.
BOOL Ptks::ObjectRead(InfoObjectStruct *pInfoObjectStruct, int dObjectStart, int dObjectNum)
{
int i;
InfoObjectStruct m_InfoObjectStruct;//Это и есть структура, она воспроизведена в C# для передачи сюда.
//Открываю файл в памятиif( FileOpen() )
{
// memcpy(pInfoObjectStruct, (LPSTR)lpFileMap[0] + sizeof(PtksFileStruct), sizeof(InfoObjectStruct) * dObjectNum);for( i = dObjectStart; i < (dObjectStart+dObjectNum); i++ )
{
//Считываю данные из отображенного файла
memcpy(&m_InfoObjectStruct, (LPSTR)lpFileMap[dServerNum] + sizeof(PtksFileStruct) + sizeof(InfoObjectStruct)*i, sizeof(InfoObjectStruct));
//Записываю данные в объект
memcpy((LPSTR)pInfoObjectStruct + sizeof(InfoObjectStruct)*i, &m_InfoObjectStruct, sizeof(InfoObjectStruct) );
}
//Освобождаю идентификаторы
FileClose();
return TRUE;
}
return FALSE;
}
Ну в принципе вот метод из dll на С++. Это вообще не наша библиотека (стороннего разработчика).
Вообще не понятно, почему из консоли работает а из службы нет?
Здравствуйте, Аноним, Вы писали: А>Вообще не понятно, почему из консоли работает а из службы нет?
Попробуйте службу запустить из под того же аккаунта, под которым работает из консоли...
логи чтоли какиенибуть в сервис встройте, коли есть код dll тожет туда логи. смотрите что происходит... ну или поставить в onStart(не помню как он называется по научному) в самое начало thread.sleep(10000); и за это времся подцепится отладчиком студии к сервису и посмотреть что происходит.
Здравствуйте, mrjeka, Вы писали:
M>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Проверь права доступа к файлу. Разрешен ли он для той учетной записи, под которой выполняется сервис ?
M>Файл существует только в памяти. Физически на диске его нет.
А это что ? Ну не файл, так мэппинг, все равно права доступа.
hFileMapping[dServerNum] = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName[dServerNum]);
// Если открыть не удалось, выводим код ошибки
>Служба запускается под тем же аком что и консоль (ну т.е. под админом)
Уверен ? А не под SYSTEM ?
В общем, совет простой. Вставь в FileOpen вывод в лог и посмотри, что не сработало.
И напиши ещё какая ОС. И кроме того, раз уж у тебя есть доступ к исходникам этого всего, ну так напихай туда ещё вызовов OutputDebugString(_T("hello")) где ошибка может быть, и смотри результат в DebugView, — сразу всё понятно станет.
Ну а сами эвенты и MMF конечно-же создаются с защитой по умолчанию, то есть с NULL вместо дескриптора защиты. И как результат — ERROR_ACCESS_DENIED. И зачем Вам EVENT_ALL_ACCESS при откратии эвента? Возьмите за правило никогда не запрашивать лишних прав, и не назначать, кстати, тоже.
А это dLastErrorCode = 1; вместо GetLastError называется "Сам себе злобный буратино". Вы же сами от себя спрятали причину сбоя, потому и локализовать проблему не смогли.
"Нормальные герои всегда идут в обход!"
Re[4]: windows service (C#) dll (c++)
От:
Аноним
Дата:
25.09.09 13:54
Оценка:
Здравствуйте, pumpurumer, Вы писали:
P>логи чтоли какиенибуть в сервис встройте, коли есть код dll тожет туда логи. смотрите что происходит... ну или поставить в onStart(не помню как он называется по научному) в самое начало thread.sleep(10000); и за это времся подцепится отладчиком студии к сервису и посмотреть что происходит.
М>Ну а сами эвенты и MMF конечно-же создаются с защитой по умолчанию, то есть с NULL вместо дескриптора защиты. И как результат — ERROR_ACCESS_DENIED.
Полагаю всё же, что проблема у автора не в нехватке прав, ведь он же сам написал, что пробовал запускать службу от имени разных учётных записей. Подозреваю, проблема в том, что та сторонняя библиотека просто изначально не была спроектирована для использоваться в многосеансовой среде (multisession environment). Хотя точно сейчас не могу сказать, зависит от ответов автора на эти
Здравствуйте, x64, Вы писали:
x64>Полагаю всё же, что проблема у автора не в нехватке прав, ведь он же сам написал, что пробовал запускать службу от имени разных учётных записей. Подозреваю, проблема в том, что та сторонняя библиотека просто изначально не была спроектирована для использоваться в многосеансовой среде (multisession environment). Хотя точно сейчас не могу сказать, зависит от ответов автора на эти
А вообще в подобных случаях лучше объекты создавать из сервиса, дабы не было проблем с правами доступа к глобальному каталогу, а из пользовательской сессии их открывать. А так ещё придётся как-то определять, в какой сессии работает процесс, создавший объекты, или перебирать все каталоги, так как эвенты без нужной привилегии в глобальном каталоге создать не получится, а она по умолчанию отсутствует, насколько помню. И даже если дело в данном случае не в этом, и сессия на машине только одна, нулевая, этот момент всё равно надо учитывать. На висте уже сессия сервисов отделена от интерактивной, и обратного хода уже не будет.
Дело в том, что dll является не нашей, а сторонней. Исходники есть, но не все. По большому счету нужно было выяснить причину неработоспособности. Т.е. уточнить, у нас косяк или в dll. Выяснилось, что метод ReadObject (метод из dll) возвращает код ошибки 2. Судя по коду, там почти половина случаев когда возвращается этот код. Поэтому эта проблема передана разработчикам этой dll'ки.
Вообще массив объектов создается на нашей стороне (C#). в dll передается указатель на массив и длина массива. Структура объектов была создана в соответствии со структурой в плюсах. (т.е. в типах полей ошибки нет).
OC Vista x64. Но приложения C# собраны под x86 (и консоль и служба).
Что касается аккаунта, под которым запускается все дело: это АДМИН(100%) — для тех кто переспрашивает не перепутал ли я его с System.
подтверждаются. 99% за то, что имена объектов не содержат префикса "Global\", что означает создание объекта в локальном сеансе (local session), т.е. в том же сеансе, что и вызывающий (caller). Дело в том, что начиная с Vista службы всегда выполняются в сеансе (код 0), отличном от сеансов приложений (код не 0). Этим объясняется работоспособность библиотеки в консольном приложении, и ошибка при использовании её в службе. Ну, в общем, с некоторыми доработками оно будет работать и в службах.