SharePoint не удается загрузить C ++ DLL в Windows 2008 - PullRequest
5 голосов
/ 04 марта 2010

У меня есть DLL-библиотека SharePoint, которая выполняет некоторые функции лицензирования, и в качестве части кода она использует внешнюю DLL-библиотеку C ++ для получения серийного номера жесткого диска.

Когда я запускаю это приложение в Windows Server 2003, оно работает нормально, но в Windows Server 2008 весь сайт (загружается при загрузке) падает и постоянно сбрасывается. Это не Windows Server 2008 R2, а то же самое в 64 или 32 битах.

Если я поставлю Debugger.Break перед выполнением DLL, я вижу, что код достигает точки разрыва, а затем никогда больше не возвращается в DLL. Я получаю некоторые предупреждения об отладочных утверждениях внутри функции, опять же только в Windows Server 2008, но я не уверен, что это связано.

Я создал консольное приложение, которое запускает C # DLL, которая, в свою очередь, загружает C ++ DLL, и это прекрасно работает на Windows Server 2008 (хотя оно показывает ошибки утверждения, но я их сейчас подавляю). Ошибки утверждения не в моем коде, а в пределах ICtypes.c, и я не могу их отлаживать.

Если я ставлю точку останова в DLL, она никогда не срабатывает, и компилятор говорит:

"step in: Stepping over non user code"

Если я пытаюсь выполнить отладку в DLL с помощью Visual Studio.

Я попытался обернуть код, используемый для вызова DLL, в:

SPSecurity.RunWithElevatedPrivileges(delegate()

Но это тоже не помогает.

У меня есть исходный код для этой DLL, так что это не проблема.

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

Если я заменю этот код жестко закодированной строкой, все приложение будет работать нормально.

Любой совет будет высоко ценится, я не могу понять, почему оно работает как консольное приложение, но не в том случае, если оно выполняется 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;
    }

Ответы [ 8 ]

3 голосов
/ 11 марта 2010

Это может быть связано с безопасностью: Важным моментом является то, что он работает в консольном приложении.

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

Напротив, консольное приложение запускается в контексте вошедшего в систему пользователя.

Попробуйте эмулировать пользователя с правами, например, когда вы запускаете консольное приложение, указанное здесь (с Undo () внутри, попробуйте / наконец, обратите внимание!). При получении токена вы можете создать SPUserToken и установить контекст сайта, используя конструктор SPSite, который принимает GUID и SPUserToken

Существует несколько примеров, документирующих этот подход, например, здесь .

РЕДАКТИРОВАТЬ: о, и причина, по которой он работал в 2003 может быть, что ваша учетная запись пула приложений имела way слишком много прав; -)

1 голос
/ 10 марта 2010

Почему бы не использовать WMI для получения серийного номера жесткого диска, что позволяет избежать выполнения неуправляемого кода. Посмотрите этот пример Как получить Серийный номер жесткого диска REAL

0 голосов
/ 17 марта 2010

Эта проблема может возникать из-за одной из проблем, перечисленных ниже.

  • веб-часть может не иметь необходимых прав для вызова DLL или

  • возможно, вы не установили соответствующий уровень доверия для своего сайта SharePoint.

Для разрешения вы можете использовать олицетворение и для уровня доверия ниже сайта может помочь вам.

http://msdn.microsoft.com/en-us/library/dd583158(office.11).aspx

0 голосов
/ 14 марта 2010

Если я поставлю точку останова в DLL, она никогда не будет достигнута, и компилятор скажет:

"step in: Stepping over non code"

Этоотладчик, а не компилятор, и если вы настроите его правильно, он этого не сделает.Ищите варианты вызовов «Использовать встроенную отладку» и «Просто мой код».Первый должен быть включен, а второй выключен.

0 голосов
/ 14 марта 2010
  1. В Visual Studio перейдите в свойства вашей исполняемой сборки и на вкладке отладки установите флажок «Включить отладку неуправляемого кода».

  2. Если импортируемый вами метод принадлежит классу, вам нужно добавить искаженное имя C ++ (например, 2 @ MyClass @ MyMethod? Zii) в качестве точки входа в атрибут DllImport (запуск зависит от собственной библиотеки DLL). чтобы получить его).

  3. Для этого вам не нужен C ++: http://www.codeproject.com/KB/cs/hard_disk_serialno.aspx

0 голосов
/ 10 марта 2010

Я создал новую C ++ DLL с нуля, которая прекрасно работает, когда на нее ссылаются как на консольное приложение в Windows Server 2003 и Windows Server 2008, но как только я обращаюсь к ней из DLL в SharePoint, происходит то же самое, и она не будет бежать.

Он находит DLL, но я думаю, что у нее нет прав на ее выполнение, даже если я помещу ее в раздел My Documents и ссылаюсь на нее напрямую!

0 голосов
/ 05 марта 2010

Я бы выяснил, если это проблема, связанная с контролем учетных записей, вы можете попробовать отключить ее. У 2003 нет UAC. Ваша учетная запись пула приложений может не иметь права на получение этой информации?

0 голосов
/ 04 марта 2010

Это недетерминированное поведение сбоя часто замечается с перезаписью / повреждением памяти; иногда это имеет значение (сбой), иногда вам везет.

Возможно, вы захотите проверить получение аварийного дампа и проанализировать его с помощью WindDbg. Поскольку у вас есть исходный код, вы можете пересобрать его с использованием различных стеков, включить системы защиты кучи и предупреждения (в зависимости от вашего компилятора) и посмотреть, что вы получите.

...