3

使用 Delphi 以编程方式检测 Lazarus IDE 是否安装在系统中的正确方法是什么?

例如要检测是否安装了 Delphi 7,我可以检查这个键HKLM\Software\Borland\Delphi\7.0

我在 Windows 注册表中搜索 Lazarus 的类似键,但我没有找到任何东西。

4

3 回答 3

7

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 系统中所需的步骤是

  1. <user name>\Local Settings\Application Data\lazarus使用SHGetSpecialFolderLocation带有CSIDL_LOCAL_APPDATA值的函数确定位置。

  2. 解析文件environmentoptions.xml以找到根LazarusDirectory下的密钥EnvironmentOptions

  3. 现在有了 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.
于 2011-03-21T20:53:14.527 回答
2

如果它驻留在 Program Files 和您的 C:\Users\your_name\AppData\Local\lazarus 中?另外,你有什么版本的SO?

LE:Lazarus 似乎没有将其数据保存在注册表中http://www.lazarus.freepascal.org/index.php?topic=9342.0

于 2011-03-21T15:31:26.207 回答
2

Afaik Lazarus 默认不安装到程序文件。这是因为在过去,FPC/Lazarus 使用的一些 GNU 工具无法处理文件名中的空格(尤其是资源编译器)。

请注意,配置文件中的设置目录只是默认目录。可以使用例如批处理文件传递自己的设置目录(使用-pcp),这是几个“棒”版本所做的事情。

此外,可能有多个 lazarus 安装(多个版本,32 位和 64 位,交叉编译器等),但只有一个可以使用 appdata 目录。

恕我直言,最好的解决方案是使其用户可配置,但要检查 c:\lazarus 和/或 appdata 目录中的 XML 文件,以找到可能的位置来播种设置。

于 2011-03-21T20:52:41.710 回答