У меня есть DLL SharePoint, который делает некоторые вещи лицензирования и как часть кода, это использует внешний C++ DLL для получения порядкового номера жесткого диска.
Когда я запускаю это приложение на Windows Server 2003, это хорошо работает, но на Windows Server 2008 целый сайт (загруженный на загрузке) катастрофические отказы и сброс постоянно. Это не Windows Server 2008 R2 и является тем же в 64 или 32 битах.
Если я поместил a Debugger.Break
перед выполнением DLL затем я вижу, что код переходит к сути дела повреждения и затем никогда, не возвращаюсь в DLL снова. Я действительно получаю некоторые предупреждения утверждения отладки из функции, снова только в Windows Server 2008, но я не уверен, что это связано.
Я создал консольное приложение, которое выполняет DLL C#, который в свою очередь загружает DLL C++, и это работает отлично над Windows Server 2008 (хотя это действительно показывает ошибки утверждения, но я подавил их теперь). Ошибки утверждения не находятся в моем коде, а в ICtypes.c
, и не что-то я могу отладить.
Если я поместил точку останова в DLL, он никогда не поражается, и в компиляторе говорится:
"step in: Stepping over non user code"
Если я пытаюсь отладить в DLL с помощью Visual Studio.
Я попытался перенестись, код раньше призывал DLL:
SPSecurity.RunWithElevatedPrivileges(delegate()
Но это также не помогает.
У меня есть исходный код для этого DLL так, чтобы не была проблема.
Если я удаляю DLL из каталога, я получаю ошибку о недостающем DLL. Если я заменяю его, назад ни к какой ошибке или предупреждению просто полного отказа.
Если я заменяю этот код строкой hardcoded, целое приложение хорошо работает.
Любой совет очень ценился бы, я не могу понять, почему он работает консольным приложением, все же не, когда выполнено SharePoint. Это с той же учетной записью пользователя на той же машине...
Это - код, используемый для вызова DLL:
[DllImport("idDll.dll", EntryPoint = "GetMachineId", SetLastError = true)]
extern static string GetComponentId([MarshalAs(UnmanagedType.LPStr)]String s);
public static string GetComponentId()
{
Debugger.Break();
if (_machine == string.Empty)
{
string temp = "";
id= ComponentId.GetComponentId(temp);
}
return id;
}
Это могло быть связано с безопасностью: {{ 1}} Важным моментом является то, что он работает в консольном приложении.
В консольном приложении RunWithElevatedPrivileges не действует, поскольку оно имитирует пользователя пула приложений для вашего рабочего процесса, пользователя, который должен иметь нет специальных прав на сам ящик.
В отличие от этого, консольное приложение запускается в контексте вошедшего в систему пользователя.
Попробуйте эмулировать пользователя с такими правами, как при запуске консольного приложения, указанного здесь (с функцией Undo () внутри попробуйте / наконец-то обратите внимание!). При получении токена вы можете создать SPUserToken и установить контекст сайта с помощью конструктора SPSite, который принимает GUID и SPUserToken
. Есть несколько примеров, документирующих этот подход, здесь , например.
РЕДАКТИРОВАТЬ: о, и причина, по которой это сработало в 2003 , могло быть в том, что у вашей учетной записи пула приложений было слишком много прав ; -)
Это недетерминированное аварийное поведение часто наблюдается при перезаписи / повреждении памяти; иногда это имеет значение (сбой), иногда вам везет.
Вы можете проверить получение аварийного дампа и проанализировать его с помощью WindDbg. Поскольку у вас есть исходный код, вы можете перестроить его с различным стеком, включив защиту памяти кучи и системы предупреждений (в зависимости от вашего компилятора) и посмотреть, что вы получите.
Я бы выяснил, не связана ли эта проблема с User Account Control, вы можете попробовать отключить его. В 2003 нет UAC. Возможно, ваша учетная запись пула приложений не имеет права получать эту информацию?
Почему бы не использовать WMI для получения серийного номера жесткого диска, таким образом избегает выполнения неуправляемого кода. См. Этот образец Как получить серийный номер НАСТОЯЩЕГО жесткого диска
Я создал новый C ++ DLL с нуля, которая отлично работает, когда на нее ссылаются как на консольное приложение в Windows Server 2003 и Windows Server 2008, но как только я ссылаюсь на нее из DLL в SharePoint, происходит то же самое, и оно не запускается.
Она находит DLL, но я думаю, что у нее нет прав на ее выполнение, даже если я помещаю ее в раздел Мои документы
и ссылаюсь на нее напрямую!
В visual studio зайдите в свойства вашей исполняемой сборки и на вкладке debug отметьте опцию enable debugging unmanaged code.
Если импортируемый вами метод принадлежит классу, вам нужно добавить искаженное C++ имя (например, 2@MyClass@MyMethod?zii) в качестве точки входа в атрибут DllImport (run зависит от родной DLL, чтобы получить его).
Для этого вам не нужен C++: http://www.codeproject.com/KB/cs/hard_disk_serialno.aspx
Если я помещаю точку останова в DLL, она никогда не попадает, а компилятор говорит:
«Шаг вперед: переход через не пользовательский код»
Это отладчик, а не компилятор, и если вы настроили его правильно, этого бы не произошло. Ищите варианты, вызывающие «Использовать встроенную отладку» и «Только мой код». Первый должен быть включен, а второй выключен.
Эта проблема может возникнуть из-за одной из проблем, перечисленных ниже.
веб-часть может не иметь прав на вызов библиотеки DLL или
возможно, вы не установили соответствующий уровень доверия для своего сайта SharePoint.
Для получения разрешения вы можете использовать олицетворение и для уровня доверия ниже сайт может вам помочь.
http://msdn.microsoft.com/en-us/library/dd583158 (office.11) .aspx