检测已安装的 lazarus IDE

发布于 2024-10-24 00:31:27 字数 189 浏览 4 评论 0 原文

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

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

我在 Windows 注册表中搜索 Lazarus 的类似密钥,但没有找到任何内容。

What is the proper way to detect if the Lazarus IDE is installed in a system programmatically using Delphi?

For example to detect if Delphi 7 is installed I can check this key HKLM\Software\Borland\Delphi\7.0.

I search for a similar key for Lazarus in the Windows registry but I don't found anything.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

阳光下慵懒的猫 2024-10-31 00:31:27

Lazarus 默认在 \Local Settings\Application Data\lazarus 文件夹中存储一个名为 environmentoptions.xml 的文件(在某些情况下,该文件可能位于其他文件夹)。该文件包含获取 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. 确定 <用户名>\Local 的位置使用 >SHGetSpecialFolderLocation 函数与 CSIDL_LOCAL_APPDATA 值。

  2. 解析文件 environmentoptions.xml 以找到 EnvironmentOptions 根目录下的 LazarusDirectory 键。

  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.

Lazarus store a file called environmentoptions.xml by default in the <user name>\Local Settings\Application Data\lazarus folder (in some scenarios this file can be located in other folder). This file contains all the info necessary to get the Lazarus IDE location as well the FPC (Free Pascal compiler) used by the IDE.

the environmentoptions.xml file look like this

<?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>

so the steps necessaries to determine if the Lazarus IDE is installed in a Windows system are

  1. Determine the location of the <user name>\Local Settings\Application Data\lazarus using the SHGetSpecialFolderLocation function with the CSIDL_LOCAL_APPDATA value.

  2. Parse the file environmentoptions.xml to locate the LazarusDirectory Key under the EnvironmentOptions root.

  3. Now with the location of the Lazarus IDE you can check the existence of the lazarus.exe file in that folder.

check this sample application which summarize all steps in this answer.

{$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.
月寒剑心 2024-10-31 00:31:27

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

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

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

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

Afaik Lazarus default does not install to Program files. This because in the past, some of the GNU tools that FPC/Lazarus uses couldn't deal with spaces in filenames (most notably the resource compiler).

Note that the settings directory in the profile is only the default directory. It is possible to pass an own settings directory (with -pcp) using e.g. a batchfile, something that several "stick" versions do.

Moreover, there might be multiple lazarus installs (multiple versions, 32-bit and 64-bit, crosscompilers etc), though then only one can use the appdata dirrectory.

The best solution IMHO is to make it user configurable, but to check c:\lazarus and/or the XML files in the appdata dir to find possible locations to seed the settings with.

难以启齿的温柔 2024-10-31 00:31:27

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

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

if it resides in Program Files and your C:\Users\your_name\AppData\Local\lazarus ?
also, what version of SO do you have?

LE: it seems that Lazarus does not keep its data in registry http://www.lazarus.freepascal.org/index.php?topic=9342.0

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文