SharePoint无法在Windows 2008上加载C ++ DLL

我有一个SharePoint DLL,它可以执行一些许可,并且作为代码的一部分,它使用外部C ++ DLL来获取硬盘的序列号。

当我在Windows Server 2003上运行此应用程序时,它工作正常,但在Windows Server 2008上,整个站点(加载时加载)会不断崩溃和重置。 这不是Windows Server 2008 R2,在64位或32位中是相同的。

如果我在DLL执行之前放置一个Debugger.Break ,那么我会看到代码到达中断点,然后再也不会再回到DLL中。 我确实从函数内部获得了一些调试断言警告,仅在Windows Server 2008中,但我不确定这是否相关。

我创建了一个运行C#DLL的控制台应用程序,后者又加载了C ++ DLL,这在Windows Server 2008上完美运行(虽然它确实显示了断言错误,但我现在已经抑制了这些)。 断言错误不在我的代码中,而是在ICtypes.c ,而不是我可以调试的东西。

如果我在DLL中放置一个断点,它永远不会被命中,编译器说:

 "step in: Stepping over non user code" 

如果我尝试使用Visual Studio调试DLL。

我已经尝试包装用于调用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; } 

可能与安全性有关:重要的一点是它可以在控制台应用程序中运行。

在控制台应用程序中,RunWithElevatedPrivileges无效,因为它模拟了工作进程的应用程序池用户,该用户对该框本身没有特殊权限。

相比之下,控制台应用程序在登录用户的上下文中运行。

尝试模拟具有权限的用户,例如当您运行此处指定的控制台应用程序时(在try / finally中使用Undo(),请注意!)。 获取令牌时,您可以使用带有GUID和SPUserToken的SPSite构造函数创建SPUserToken并建立站点上下文

这里有几个例子记录了这种方法,例如。

编辑:哦,它在2003年的工作原因可能是你的应用程序池帐户有太多的权利;-)

为什么不使用WMI来获取硬盘的序列号,从而避免执行非托管代码。 请参阅此示例如何检索REAL硬盘驱动器序列号

内存覆盖/损坏经常会出现这种非确定性崩溃行为; 有时它很重要(崩溃),有时你会很幸运。

您可能想要检查获取崩溃转储并使用WindDbg进行分析。 由于您拥有源代码,因此可以使用各种堆栈,堆内存保护和警告系统(取决于您的编译器)重新构建它,并查看您获得的内容。

我会发现它是否是与用户帐户控制相关的问题,您可以尝试禁用它。 2003年没有UAC。 您的应用池帐户可能无权检索此信息?

  1. 在visual studio中,进入可执行程序集的属性,然后在调试选项卡下,选中enable debugging unmanaged code选项。

  2. 如果要导入的方法属于某个类,则需要添加受损的C ++名称(例如2 @ MyClass @ MyMethod?zii)作为DllImport属性的入口点(运行取决于本机DLL来获取它)。

  3. 你不需要C ++: http : //www.codeproject.com/KB/cs/hard_disk_serialno.aspx

如果我在DLL中放置一个断点,它永远不会被命中,编译器说:

“介入:踩过非用户代码”

这是调试器,而不是编译器,如果你正确配置它就不会那样做。 查找选项调用“使用本机调试”和“仅我的代码”。 第一个应该打开,第二个打开。

由于下面列出的问题之一,可能会发生此问题。

  • Web部件可能没有正确的权限来调用DLL或

  • 您可能没有为SharePoint站点设置适当的信任级别。

对于权限,您可以使用模拟,并且对于网站下面的信任级别可以帮助您。

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

我从头开始制作了一个新的C ++ DLL,当它作为Windows Server 2003和Windows Server 2008上的控制台应用程序引用时工作正常,但是一旦我从SharePoint中的DLL引用它,就会发生相同的事情,它将无法运行。

它确实找到了DLL,但我认为它没有执行权限,即使我将它放入My Documents部分并直接引用它!