【发布时间】:2016-05-16 07:17:36
【问题描述】:
我使用 Delphi XE7,我们的一个大型遗留应用程序仍然广泛使用带有 Paradox 表的 BDE。我知道 BDE 已被弃用,但我们对这个应用别无选择。
此应用当前在运行时和启动时设置 BDE 别名。它使用BDE提供的标准默认Session,并使用“TSession.AddStandardAlias”添加别名,并引用数据模块中定义的许多表。
我现在需要能够在应用程序运行后更改别名引用的文件夹路径,但发现它存在问题。基本上,它似乎可以工作,但是在更改别名后它仍然以某种方式引用以前的路径。甚至“TSession.GetAliasParams”也报告了新路径,但随后在 Bde.DBTables 中出现错误,因为它正在尝试访问不再存在的先前路径。
鉴于应用程序很大,我在以下示例项目中重现了类似的问题。如果有人愿意尝试,这是一个非常简单的应用程序,只有主窗体。您需要设置两个文件夹,并将任何 Paradox 表放到一个文件夹中,然后在“编辑”框中指定该文件夹的路径,然后按“设置别名路径”按钮,这将设置别名,然后写入按钮下方的标签,告诉您别名所指的路径。然后“查找表”按钮和编辑框使用“TSession.GetTableNames”查找是否存在表。
最简单的方法是设置两个文件夹“C:\TEMP\testBDE\path1”和“C:\TEMP\testBDE\path2”,然后在运行应用程序时将任何 Paradox 表放入 path1 “设置别名路径”按钮,然后按“查找表”按钮,它会报告该表存在。
然后改别名引用path2,为空,报指向path2,同时报表存在。然后很容易将表从path1移动到path2,然后它会报告表不存在。
任何建议将不胜感激。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
Bde.DBTables;
const
myAlias = 'ALIAS1';
function getPathFromAlias(tempAlais : String ): String;
var
MyStringList : TStringList;
i, k: integer;
tempStr, newDirectory: String;
begin
newDirectory:='';
MyStringList := TStringList.Create;
try
Session.GetAliasParams(tempAlais,MyStringList);
{ fill stringlist with driver names }
for i := 0 to MyStringList.count-1 do
begin
tempStr:= uppercase(trim(MyStringList.Strings[i]));
k := pos('PATH=', tempStr);
if k > 0 then
begin
delete(tempStr,1, k+4);
newDirectory:=tempStr;
end;
end;
finally
MyStringList.Free;
end;
result:=newDirectory;
end;
procedure setAliases( apath : String);
var
MyStringList : TStringList;
begin
(*
MyStringList := TStringList.Create;
try
MyStringList.Add( 'PATH='+apath);
MyStringList.Add( 'ENABLE BCD=FALSE');
MyStringList.Add( 'DEFAULT DRIVER=PARADOX');
Session.ConfigMode := cmSession;
if Session.IsAlias( myAlias) then
Session.ModifyAlias( myAlias, MyStringList)
else
Session.AddStandardAlias( myAlias, apath, 'PARADOX');
Session.ConfigMode := cmSession;
finally
MyStringList.Free;
end;
*)
Session.ConfigMode := cmSession;
if Session.IsAlias( myAlias) then
Session.DeleteAlias( myAlias);
Session.AddStandardAlias( myAlias, apath, 'PARADOX');
Session.ConfigMode := cmSession;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
setAliases( Edit1.Text);
Label1.Caption := getPathFromAlias( myAlias);
end;
function TableExists(const aDataBaseName, aTableName:string): Boolean;
var
TableNames: TStringList;
begin
TableNames:=TStringList.Create;
try
Session.GetTableNames(aDatabaseName,'',True,False,TableNames);
Result:=(TableNames.IndexOf(aTableName)<>-1);
finally
TableNames.Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
temps : String;
myTable : TTable;
begin
if TableExists( myAlias, Edit2.Text) then
Label2.Caption := 'Exists'
else
Label2.Caption := 'Not found'
end;
end.
【问题讨论】:
-
什么是操作系统?包含 BDE 别名的文件的完整路径是什么?
-
抱歉,这是 Windows 7。我没有使用 BDE 配置文件,实际遗留应用程序中的别名是在运行时创建的,它们引用的路径来自另一个启动的应用程序旧版应用程序。这些路径基于原始安装文件夹。
-
Vista+ 具有所谓的“虚拟存储”,因此部分文件并没有真正位于应用程序读取和写入它们的位置。当您的应用程序保存/读取别名时,使用 SysInternals Process Monitor 之类的工具并拦截文件 I/O 日志,检查它们匹配的文件名,然后尝试查看磁盘上是否存在两个别名文件(默认为“idapi32.cfg”),在默认位置和虚拟商店中 - 它们可能重叠。还尝试“以管理员身份”运行您的应用程序 - 即使用“UAC 提升” - 这会暂时停用进程 AFAIR 的虚拟商店
标签: delphi