使用 Delphi 以编程方式检测 Lazarus IDE 是否安装在系统中的正确方法是什么?
例如要检测是否安装了 Delphi 7,我可以检查这个键HKLM\Software\Borland\Delphi\7.0
。
我在 Windows 注册表中搜索 Lazarus 的类似键,但我没有找到任何东西。
Lazarus 在文件夹中存储一个environmentoptions.xml
默认调用的<user name>\Local Settings\Application Data\lazarus
文件(在某些情况下,该文件可以位于其他文件夹中)。该文件包含获取 Lazarus IDE 位置以及 IDE 使用的 FPC(Free Pascal 编译器)所需的所有信息。
environmentoptions.xml
文件看起来像这样
<?xml version="1.0"?>
<CONFIG>
<EnvironmentOptions>
<Version Value="106"/>
<LazarusDirectory Value="C:\lazarus\">
<History Count="1">
<Item1 Value="C:\lazarus\"/>
</History>
</LazarusDirectory>
<CompilerFilename Value="C:\lazarus\fpc\2.2.4\bin\i386-win32\fpc.exe">
<History Count="3">
<Item1 Value="C:\fpc\2.2.4\bin\i386-win32\fpc.exe"/>
<Item2 Value="C:\lazarus\fpc\2.2.4\bin\i386-win32\fpc.exe"/>
<Item3 Value="C:\lazarus\fpc\2.4.2\bin\i386-win32\fpc.exe"/>
</History>
</CompilerFilename>
<FPCSourceDirectory Value="c:\lazarus\fpc\2.2.4\source\">
<History Count="1">
<Item1 Value="c:\lazarus\fpc\2.2.4\source\"/>
</History>
</FPCSourceDirectory>
<MakeFilename Value="C:\lazarus\fpc\2.2.4\bin\i386-win32\make.exe">
<History Count="2">
<Item1 Value="C:\fpc\2.2.4\bin\i386-win32\make.exe"/>
<Item2 Value="C:\lazarus\fpc\2.2.4\bin\i386-win32\make.exe"/>
</History>
</MakeFilename>
<TestBuildDirectory Value="C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\">
<History Count="3">
<Item1 Value="C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\"/>
<Item2 Value="C:\temp\"/>
<Item3 Value="C:\windows\temp\"/>
</History>
</TestBuildDirectory>
<BackupProjectFiles AdditionalExtension="bak" MaxCounter="9"/>
<BackupOtherFiles AdditionalExtension="bak" MaxCounter="9"/>
<Debugger Class="TGDBMIDebugger" EventLogLineLimit="100"/>
<DebuggerFilename Value="c:\lazarus\mingw\bin\gdb.exe">
<History Count="4">
<Item1 Value="c:\lazarus\mingw\bin\gdb.exe"/>
<Item2 Value="/usr/bin/gdb"/>
<Item3 Value="/usr/local/bin/gdb"/>
<Item4 Value="/opt/fpc/gdb"/>
</History>
</DebuggerFilename>
<Recent>
<OpenFiles Max="10" Count="10">
</OpenFiles>
<ProjectFiles Max="5" Count="5">
</ProjectFiles>
<PackageFiles Max="10" Count="1">
<Item1 Value="C:\Librerias\Indy10\Lib\indylaz.lpk"/>
</PackageFiles>
</Recent>
<ExternalTools Count="0"/>
<CharcaseFileAction Value="Ask"/>
<CompilerMessagesFilename Value=""/>
</EnvironmentOptions>
<ObjectInspectorOptions ShowHints="False" InfoBoxHeight="50">
<Version Value="3"/>
<ComponentTree>
<Height Value="97"/>
</ComponentTree>
</ObjectInspectorOptions>
</CONFIG>
因此确定 Lazarus IDE 是否安装在 Windows 系统中所需的步骤是
<user name>\Local Settings\Application Data\lazarus
使用SHGetSpecialFolderLocation
带有CSIDL_LOCAL_APPDATA
值的函数确定位置。
解析文件environmentoptions.xml
以找到根LazarusDirectory
下的密钥EnvironmentOptions
。
现在有了 Lazarus IDE 的位置,您可以检查该lazarus.exe
文件夹中的文件是否存在。
检查此示例应用程序,它总结了此答案中的所有步骤。
{$APPTYPE CONSOLE}
uses
ShlObj,
ComObj,
ActiveX,
Classes,
Windows,
Variants,
SysUtils;
function GetLocalAppDataFolder : string;
const
CSIDL_LOCAL_APPDATA = $001C;
var
ppMalloc : IMalloc;
ppidl : PItemIdList;
begin
ppidl := nil;
try
if SHGetMalloc(ppMalloc) = S_OK then
begin
SHGetSpecialFolderLocation(0, CSIDL_LOCAL_APPDATA, ppidl);
SetLength(Result, MAX_PATH);
if not SHGetPathFromIDList(ppidl, PChar(Result)) then
RaiseLastOSError;
SetLength(Result, lStrLen(PChar(Result)));
end;
finally
if ppidl <> nil then
ppMalloc.free(ppidl);
end;
end;
function GetLazarusLocalFolder : string;
begin
Result:=Format('%slazarus',[IncludeTrailingPathDelimiter(GetLocalAppDataFolder)]);
if not DirectoryExists(Result) then
Result:='';
end;
function FileToString(const FileName: TFileName): AnsiString;
var
Stream : TFileStream;
begin
Stream:=TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
try
SetLength(Result, Stream.Size);
Stream.Read(Pointer(Result)^, Stream.Size);
except
Result:='';
end;
finally
Stream.Free;
end;
end;
function GetLazarusFolder : string;
var
LocalFolder : TFileName;
FileName : TFileName;
XmlDoc : OleVariant;
Node : OleVariant;
begin
Result:='';
LocalFolder:=GetLazarusLocalFolder;
if LocalFolder<>'' then
begin
FileName:=IncludeTrailingPathDelimiter(LocalFolder)+'environmentoptions.xml';
if FileExists(FileName) then
begin
XmlDoc := CreateOleObject('Msxml2.DOMDocument.6.0');
try
XmlDoc.Async := False;
XmlDoc.LoadXML(FileToString(FileName));
XmlDoc.SetProperty('SelectionLanguage','XPath');
if (XmlDoc.parseError.errorCode <> 0) then
raise Exception.CreateFmt('Error in Xml Data %s',[XmlDoc.parseError]);
Node :=XmlDoc.selectSingleNode('//CONFIG/EnvironmentOptions/LazarusDirectory/@Value');
if not VarIsClear(Node) then
Result:=Node.text;
finally
XmlDoc:=Unassigned;
end;
end;
end;
end;
function IsLazarusInstalled : Boolean;
begin
Result:=FileExists(IncludeTrailingPathDelimiter(GetLazarusFolder)+'lazarus.exe');
end;
begin
try
CoInitialize(nil);
try
Writeln('Lazarus config Folder '+GetLazarusLocalFolder);
Writeln('Lazarus Install folder '+GetLazarusFolder);
Writeln('Is Lazarus Installed '+BoolToStr(IsLazarusInstalled,True));
Readln;
finally
CoUninitialize;
end;
except
on E:Exception do
begin
Writeln(E.Classname, ':', E.Message);
Readln;
end;
end;
end.
如果它驻留在 Program Files 和您的 C:\Users\your_name\AppData\Local\lazarus 中?另外,你有什么版本的SO?
LE:Lazarus 似乎没有将其数据保存在注册表中http://www.lazarus.freepascal.org/index.php?topic=9342.0
Afaik Lazarus 默认不安装到程序文件。这是因为在过去,FPC/Lazarus 使用的一些 GNU 工具无法处理文件名中的空格(尤其是资源编译器)。
请注意,配置文件中的设置目录只是默认目录。可以使用例如批处理文件传递自己的设置目录(使用-pcp),这是几个“棒”版本所做的事情。
此外,可能有多个 lazarus 安装(多个版本,32 位和 64 位,交叉编译器等),但只有一个可以使用 appdata 目录。
恕我直言,最好的解决方案是使其用户可配置,但要检查 c:\lazarus 和/或 appdata 目录中的 XML 文件,以找到可能的位置来播种设置。