1

我在使用 Sybase 驱动程序时遇到了问题。当 Sybase 尝试创建连接时,我得到以下信息。

[AseException: Could not load C:\Windows\TEMP\Sybase.AdoNet4.AseClient.32bits.4.157.501.0\sbgse2.dll]
   Sybase.Data.AseClient1.AseConnection.SaveAndLoadLibrary(String dirName, String dllName, Int32 bits) +419
   Sybase.Data.AseClient1.AseConnection.LoadLibraries() +243
   Sybase.Data.AseClient1.AseConnection..cctor() +5

[TypeInitializationException: The type initializer for 'Sybase.Data.AseClient1.AseConnection' threw an exception.]
   Sybase.Data.AseClient1.AseConnection..ctor(AseConnection realConnection) +0
   Sybase.Data.AseClient.AseConnection..ctor() +27

我看到 Sybase 将一些非托管代码编译为嵌入式资源,然后在运行时如果这些文件不在 temp 目录中,它会将它们复制到那里。

就我而言,我看到这些文件确实存在。我什至可以删除它们并看到它们在运行时被复制回来。

我现在很困惑为什么它们不能被加载。

这台机器曾经运行.net 4.5。它被卸载并重新安装了 .net 4.0。不确定这与它有什么关系。

这里是sybase驱动中的相关代码

    private static void LoadLibraries()
   {
     int bits = IntPtr.Size * 8;
     string str = Path.Combine(Path.GetTempPath(),    Assembly.GetExecutingAssembly().GetName().Name + "." + bits.ToString() + "bits." +    ((object) Assembly.GetExecutingAssembly().GetName().Version).ToString());
     if (!Directory.Exists(str))
       Directory.CreateDirectory(str);
       Sybase.Data.AseClient1.AseConnection.SaveAndLoadLibrary(str, "sbgse2.dll",   bits);
     Sybase.Data.AseClient1.AseConnection.SaveAndLoadLibrary(str, "sybdrvado20.dll", bits);
   }

   private static void SaveAndLoadLibrary(string dirName, string dllName, int bits)
   {
     string str = Path.Combine(dirName, dllName);
     if (!File.Exists(str))
     {
       using (Stream manifestResourceStream =    Assembly.GetExecutingAssembly().GetManifestResourceStream("Sybase.Data.AseClient.Resources._" + bits.ToString() + "bits." + dllName))
       {
         try
         {
           using (Stream stream = (Stream) File.Create(str))
           {
             byte[] buffer = new byte[4096];
             while (true)
             {
               int count = manifestResourceStream.Read(buffer, 0, 4096);
               if (count >= 1)
                 stream.Write(buffer, 0, count);
               else
                 break;
             }
             stream.Close();
           }
         }
         catch
         {
         }
       }
     }
     if (Sybase.Data.AseClient1.AseConnection.LoadLibrary(str) == IntPtr.Zero)
       throw new AseException("Could not load " + str);
  }

   [DllImport("kernel32.dll")]
   public static IntPtr LoadLibrary(string dllToLoad);

有什么想法或想法吗?

4

4 回答 4

1

似乎(出于某种原因)复制到 c:\windows\temp 的文件从初始化此代码的 AppPool 获得了特殊权限,导致其他应用程序池无法读取该文件。为此,我预计会出现 Access Denied 类型异常。

充其量它仍然有点神奇和挥手,但是从文件中删除应用程序池的特殊权限,删除临时目录并重新启动使出错的应用程序(在不同的应用程序池中)不会引发此异常。特殊权限也没有重新出现在临时文件上。

于 2013-03-06T16:40:27.073 回答
0

由于所有应用程序池身份都必须在 IIS 工作进程组中,因此解决方案是为 IIS 组授予对C:\Windows\TEMP文件夹的修改权限:

  • IIS 6IIS_WPG
  • IIS 7IIS_IUSRS

权限将被正确继承(在 Windows Server 2008 和 IIS 7 上验证)。

于 2013-05-21T12:32:06.190 回答
0

最终对我有用的是将应用程序池分配给相同的身份。

  1. 停止两个应用程序池
  2. 删除目录“Wi​​ndows\temp\Sybase.AdoNet4.AseClient.32bits.4.157.1000.0
  3. 将身份网络服务分配给两个应用程序池
  4. 启动两个应用程序池。
  5. 一切都应该工作。

  6. 执行步骤 1 和 2。

  7. 通过转到“控制面板 > 管理工具 > 计算机管理 > 本地用户和组 > 用户”创建自定义标识
  8. 右键单击并选择“新用户...”
  9. 添加新的用户名和密码
  10. 单击创建按钮并关闭对话框
  11. 在 IIS 中,选择第一个应用程序池 > 高级设置
  12. 单击身份字段>单击...按钮
  13. 选择自定义账户,点击设置...按钮
  14. 输入新的用户帐户信息,单击确定
  15. 单击确定关闭应用程序池标识对话框
  16. 单击确定关闭高级设置。
  17. 对第二个应用程序池重复步骤 11-16
  18. 执行第 4 步。

最后一点,在 web.config 中,您可能需要在 system.serviceModel 部分的标签 serviceHostingEnvironment 中指定 multipleSiteBindingsEnabled="true"。

于 2015-10-30T12:15:20.640 回答
0

尝试将 AppPool 上的标识从 ApplicationPoolIdentity 更改为 LocalSystem。

于 2019-04-26T10:57:05.000 回答