gpt4 book ai didi

delphi - 在处理传入请求之前,如何在 'TISAPIApplication` 中建立 ADO 数据库连接?

转载 作者:行者123 更新时间:2023-12-01 16:35:12 27 4
gpt4 key购买 nike

TADOConnection 在 Delphi ISAPI 应用程序 (TISAPIApplication) 的应用程序初始化部分中连接失败:

应用程序是使用 Delphi XE SPI 构建的,运行 Win 7 64/IIS 7.5 和 WinServer 2008 RS2 - 它无法在全局 ISAPI 应用程序上下文中与 ADO 连接。 (示例代码使用 MS-SQLServer OLEDB - 但我们使用 Sybase ASE 提供程序也失败。)

调用 conn.Open 时,以下代码失败 - TADOConnection.open 永远不会返回 - ISAPI 应用程序在 la-la land 中挂起,没有引发异常:

library ISAPIBareBones;

uses
ActiveX,
ADODB,

(...)

var
conn: TADOConnection;

begin

CoInitFlags := COINIT_MULTITHREADED;
Application.Initialize;

coinitialize(nil);
conn := TADOConnection.Create(Application);
conn.ConnectionString := 'Provider=SQLOLEDB.1;xxx';

//Fails here:

try
conn.Open;
except on e:exception do
logException(e)
end;


Application.WebModuleClass := WebModuleClass;
Application.Run;

end.

特定请求处理程序(Delphi webAction)中的相同代码运行良好。

我们怀疑 IIS 中 ISAPI 应用程序级别的执行权限存在问题。但据我们所知,从 web 服务器本身到特定虚拟目录以及 ISAPI dll 本身的整个 IIS 应用程序堆栈都在具有相同执行权限的相同凭据下运行。

同时,我的解决方法是从 http 响应调用(ISAPI 线程)中初始化数据库基础结构,然后简单地检查它是否在每个后续调用中都已初始化。这可行,但给我带来了一些我不想处理的限制。

在处理传入请求之前,如何在 TISAPIApplication 实例中建立 ADO 数据库连接。

最佳答案

dll 的 begin ... endinitialization 部分在 Delphi 中相当于 C++ 中的 dllmain。因此,同样的限制也适用,包括:

  • 不要调用 CoInitialize
  • 不要调用 COM 函数

这意味着您无法创建 ADO 连接。

您知道调用 TADOConnection.Create(Application); 时发生的所有事情吗?

所以你想做的事情是行不通的。即使确实如此,你也不应该这样做。这里有一些更好的解释:

http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx
http://blogs.msdn.com/b/oldnewthing/archive/2004/01/27/63401.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2014/08/21/10551659.aspx

MSDN suggests在 GetExtensionVersion 中创建数据库连接。这就是 isapi dll 的初始化方式。它不仅仅是用于报告扩展版本。所以这就是要走的路。创建您自己的 GetExtensionVersion 函数来初始化数据库,然后调用前面的 Delphi 函数。

library Project1;

uses
Winapi.ActiveX,
System.Win.ComObj,
Web.WebBroker,
Web.Win.ISAPIApp,
Web.Win.ISAPIThreadPool,
Winapi.Isapi2,
Winapi.Windows,
WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule};

{$R *.res}

function GetExtensionVersion(var Ver: THSE_VERSION_INFO): BOOL; stdcall;
begin
Result := Web.Win.ISAPIApp.GetExtensionVersion(Ver);
// create your ado connection here
end;


exports
GetExtensionVersion,
HttpExtensionProc,
TerminateExtension;

begin
CoInitFlags := COINIT_MULTITHREADED;
Application.Initialize;
Application.WebModuleClass := WebModuleClass;
Application.Run;
end.

关于delphi - 在处理传入请求之前,如何在 'TISAPIApplication` 中建立 ADO 数据库连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7264136/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com