Difference between revisions of "FileAssociation"

From Lazarus wiki
Jump to navigationJump to search
(Created page with "==FileAssociation== '''Package Name:''' fileassoc.lpk '''Component Name:''' TFileAssociation (fileassociation.pas) With this component you can easily register file associati...")
 
m (Remove duped platform template)
 
(23 intermediate revisions by 7 users not shown)
Line 1: Line 1:
==FileAssociation==
+
{{FileAssociation}}
  
'''Package Name:''' fileassoc.lpk
+
== TFileAssociation ==
'''Component Name:''' TFileAssociation (fileassociation.pas)
 
  
With this component you can easily register file associations for all Windows versions. This includes Windows Vista/7/8 Default Programs feature.
+
Author: Lainz
  
Install like any package. The component is under the "System" tab.
+
Licence: Modified LGPL
  
==License==
+
Version: 1.0
LGPL (The same as Lazarus).
 
  
==Intended platform==
+
Description: This unit registers file association for Windows.
Win32, Win64.
 
  
==Status==
+
== Download ==
Stable.
 
  
==Where to download it:==
+
GitHub: https://github.com/lainz/FileAssociation
[http://lazarus.freepascal.org/index.php/topic,19941.0.html Download (in Lazarus Forum)]
 
  
==Who wrote it==
+
== Usage ==
Lainz.
 
  
==Is support available==
+
First install the package. You can then drop the component TFileAssociation (FileAssoc unit) that gets installed in the [[System tab]] of the IDE on your [[TForm|form]].
  
Yes, Ask in the lazarus forum, the same page that contains the download.
+
All parameters are mandatory. Especially ActionName which must be 'Open' to work with double click. This is useful as well for default commands like 'Edit' and 'Print'. This must be in English for 'Edit', 'Open' and 'Print' so it can access the right registry entry. You can customize the translation with ActionText.
  
==Test (included in download)==
+
<syntaxhighlight lang="pascal">
 +
...
 +
uses
 +
  ...
 +
  FileAssoc; //<-- add fileassociation unit here
  
This register file association for lazarus.
+
type
 
 
[[File:fileassoc.png]]
 
 
 
Add a TFileAssociation in the form, a TButton, a TDirectoryEdit and then write this code:
 
<syntaxhighlight>
 
const
 
  lazExe = 'lazarus.exe';
 
  
 +
...
 +
    { private declarations }
 +
    assoc: TFileAssociation;
 
...
 
...
  
procedure TForm1.btnExecClick(Sender: TObject);
+
procedure TfrmMain.FormCreate(Sender: TObject);
var
 
  lazExePath: string;
 
  AddedToAll: boolean;
 
 
begin
 
begin
   lazExePath := lazDir.Directory + PathDelim + lazExe;
+
   assoc := TFileAssociation.Create(Self);//<-- create like a regular component
  if FileExistsUTF8(lazExePath) then
+
end;
  begin
 
    assoc.CmdData := '"' + lazExePath + '" "%1"';
 
    assoc.CmdIcon := lazExePath;
 
  
    // if you leave it empty the system will use localized 'Open' ('Abrir', 'Ouvrir', etc..)
+
procedure TfrmMain.Button1Click(Sender: TObject);
    // it works for CmdNameNoSpaces 'Open', 'Edit', 'Print'
+
begin
    // assoc.CmdName := 'Open with Lazarus';
+
  assoc.ApplicationName := 'Lazarus IDE';
 +
  assoc.ApplicationDescription := 'RAD for Free Pascal';
  
    assoc.ExtData := '.lfm';
+
  // you can change Extension and Action part for each extension you have
    assoc.ExtIcon := lazDir.Directory + '\images\LazarusForm.ico';
 
    assoc.ExtName := 'Lazarus Form';
 
    assoc.ExtNameNoSpaces := 'LazarusForm';
 
  
    // if can't add to all users try to add to single user
+
  assoc.Extension := '.lpr';
    if not assoc.Execute then
+
  assoc.ExtensionName := 'Lazarus Project';
    begin
+
  assoc.ExtensionIcon := '"C:\lazarus\images\lprfile.ico"';
      AddedToAll := False;
 
      assoc.RegisterForAllUsers := False;
 
      // if doesn't works..
 
      if not assoc.Execute then
 
      begin
 
        ShowMessage('Can not write to registry');
 
        Exit;
 
      end;
 
    end
 
    else
 
      AddedToAll := True;
 
  
    // it needs to be called only one time
+
  // full path required, you can use ParamStr(0) to get the path with the .exe name included. The path must be inside quotes if it has whitespace.
    assoc.AddAppToDefaultPrograms := False;
+
  assoc.Action := '"C:\lazarus\lazarus.exe" "%1"';
 +
  assoc.ActionName := 'Open';
 +
  assoc.ActionIcon := '"C:\lazarus\images\mainicon.ico"';
  
    assoc.ExtData := '.lpi';
+
  // notice that using RegisterForAllUsers as True requires Administrator Privileges
    assoc.ExtIcon := lazDir.Directory + '\images\LazarusProject.ico';
+
  // if you want to run without privileges set it to false, but it will register for current user only
     assoc.ExtName := 'Lazarus Project Information';
+
  assoc.RegisterForAllUsers:=False;
    assoc.ExtNameNoSpaces := 'LazarusProjectInformation';
+
  if assoc.Execute then
    assoc.Execute;
+
  begin
 +
    ShowMessage('OK');
 +
     assoc.ClearIconCache; //<<-- rebuild icons
 +
  end;
 +
end;
  
    assoc.ExtData := '.lpk';
+
end.
    assoc.ExtIcon := lazDir.Directory + '\images\lazaruspackage.ico';
+
</syntaxhighlight>
    assoc.ExtName := 'Lazarus Package';
 
    assoc.ExtNameNoSpaces := 'LazarusPackage';
 
    assoc.Execute;
 
  
    assoc.ExtData := '.lpr';
+
== How to open the associated file ==
    assoc.ExtIcon := lazDir.Directory + '\images\lprfile.ico';
 
    assoc.ExtName := 'Lazarus Program';
 
    assoc.ExtNameNoSpaces := 'LazarusProgram';
 
    assoc.Execute;
 
  
    assoc.ExtData := '.inc';
+
<syntaxhighlight lang="pascal">
     assoc.ExtIcon := lazDir.Directory + '\images\includefile.ico';
+
procedure TForm1.FormCreate(Sender: TObject);
     assoc.ExtName := 'Include File';
+
var
     assoc.ExtNameNoSpaces := 'IncludeFile';
+
  s: String;
    assoc.Execute;
+
begin
 +
// if there are parameters
 +
  if ParamCount > 0 then
 +
  begin
 +
// load the first parameter
 +
     s := ParamStr(1);
 +
 +
// if is a .txt file
 +
    if ExtractFileExt(s) = '.txt' then
 +
     begin
 +
// load the .txt file into a memo
 +
      Memo1.Lines.LoadFromFile(s);
 +
     end;
 +
  end;
 +
end;  
 +
</syntaxhighlight>
  
    assoc.ExtData := '.pas';
+
== Another way of registering file associations ==
    assoc.ExtIcon := lazDir.Directory + '\images\lprfile.ico';
 
    assoc.ExtName := 'Pascal Source Code';
 
    assoc.ExtNameNoSpaces := 'PascalSourceCodePAS';
 
    assoc.Execute;
 
  
    assoc.ExtData := '.pp';
+
Without using the component is as well possible to register a file association. This however doesn't cover adding the application to Default Programs, but is shorter if you only want to register a file type that's owned by your application.
    assoc.ExtIcon := lazDir.Directory + '\images\lprfile.ico';
 
    assoc.ExtName := 'Pascal Source Code';
 
    assoc.ExtNameNoSpaces := 'PascalSourceCodePP';
 
    assoc.Execute;
 
  
     // refresh icon cache
+
<syntaxhighlight lang="pascal">
     assoc.ClearIconCache;
+
{$IFDEF WINDOWS}
 +
uses Registry, ShlObj;
 +
 +
procedure TMainForm.RegisterFileType(ExtName: string; AppName: string);
 +
var
 +
  reg: TRegistry;
 +
begin
 +
  reg := TRegistry.Create;
 +
  try
 +
    reg.RootKey := HKEY_CLASSES_ROOT;
 +
    reg.OpenKey('.' + ExtName, True);
 +
    reg.WriteString('', ExtName + 'file');
 +
    reg.CloseKey;
 +
    reg.CreateKey(ExtName + 'file');
 +
    reg.OpenKey(ExtName + 'file\DefaultIcon', True);
 +
    reg.WriteString('', AppName + ',0');
 +
    reg.CloseKey;
 +
    reg.OpenKey(ExtName + 'file\shell\open\command', True);
 +
     reg.WriteString('', AppName + ' "%1"');
 +
    reg.CloseKey;
 +
  finally
 +
     reg.Free;
 +
  end;
 +
  SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
 +
end;
 +
{$ENDIF}
 +
</syntaxhighlight>
  
     if AddedToAll then
+
<syntaxhighlight lang="pascal">
      ShowMessage('File Association Registered for All Users.')
+
var
    else
+
  reg: TRegistry;
       ShowMessage('File Association Registered for Current User.' +
+
     
        LineEnding +
+
begin
        'If you want to register for All Users run this program with Administrative Privileges.');
+
  {$IFDEF WINDOWS}
   end
+
  reg := TRegistry.Create;
   else
+
  try
     ShowMessage(format('The directory %0:s does not contain %1:s.',
+
    reg.RootKey := HKEY_CLASSES_ROOT;
       ['"' + lazDir.Directory + '"', '"' + lazExe + '"']));
+
     if not reg.KeyExists('ext' + 'file\shell\open\command') then
end;
+
       RegisterFileType('ext', ExtractFilePath(Application.ExeName) + 'my_app.exe');
 +
  finally
 +
    reg.Free;
 +
   end;
 +
 +
if ParamCount > 0 then
 +
   begin
 +
     s := ParamStr(1);
 +
    if ExtractFileExt(s) = '.ext' then
 +
       LoadFile(s);
 +
  end;
 +
  {$ENDIF}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
== See also ==
 +
 +
If this component for some reason does not work for you, or you need to run it as administrator for all users without elevating your application privileges, an [[Inno_Setup_Usage#File_Association|Inno Setup Script]] may fit your needs best.

Latest revision as of 04:38, 15 February 2020

Windows logo - 2012.svg

This article applies to Windows only.

See also: Multiplatform Programming Guide

English (en) français (fr)

TFileAssociation

Author: Lainz

Licence: Modified LGPL

Version: 1.0

Description: This unit registers file association for Windows.

Download

GitHub: https://github.com/lainz/FileAssociation

Usage

First install the package. You can then drop the component TFileAssociation (FileAssoc unit) that gets installed in the System tab of the IDE on your form.

All parameters are mandatory. Especially ActionName which must be 'Open' to work with double click. This is useful as well for default commands like 'Edit' and 'Print'. This must be in English for 'Edit', 'Open' and 'Print' so it can access the right registry entry. You can customize the translation with ActionText.

...
uses
  ...
  FileAssoc; //<-- add fileassociation unit here

type

...
    { private declarations }
    assoc: TFileAssociation;
...

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  assoc := TFileAssociation.Create(Self);//<-- create like a regular component
end;

procedure TfrmMain.Button1Click(Sender: TObject);
begin
  assoc.ApplicationName := 'Lazarus IDE';
  assoc.ApplicationDescription := 'RAD for Free Pascal';

  // you can change Extension and Action part for each extension you have

  assoc.Extension := '.lpr';
  assoc.ExtensionName := 'Lazarus Project';
  assoc.ExtensionIcon := '"C:\lazarus\images\lprfile.ico"';

  // full path required, you can use ParamStr(0) to get the path with the .exe name included. The path must be inside quotes if it has whitespace.
  assoc.Action := '"C:\lazarus\lazarus.exe" "%1"'; 
  assoc.ActionName := 'Open';
  assoc.ActionIcon := '"C:\lazarus\images\mainicon.ico"';

  // notice that using RegisterForAllUsers as True requires Administrator Privileges
  // if you want to run without privileges set it to false, but it will register for current user only
  assoc.RegisterForAllUsers:=False;
  if assoc.Execute then
  begin
    ShowMessage('OK');
    assoc.ClearIconCache; //<<-- rebuild icons
  end;
end;

end.

How to open the associated file

procedure TForm1.FormCreate(Sender: TObject);
var
  s: String;
begin
// if there are parameters
  if ParamCount > 0 then
  begin
// load the first parameter
    s := ParamStr(1);
 
// if is a .txt file
    if ExtractFileExt(s) = '.txt' then
    begin
// load the .txt file into a memo
      Memo1.Lines.LoadFromFile(s);
    end;
  end;
end;

Another way of registering file associations

Without using the component is as well possible to register a file association. This however doesn't cover adding the application to Default Programs, but is shorter if you only want to register a file type that's owned by your application.

{$IFDEF WINDOWS}
uses Registry, ShlObj;
 
procedure TMainForm.RegisterFileType(ExtName: string; AppName: string);
var
  reg: TRegistry;
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_CLASSES_ROOT;
    reg.OpenKey('.' + ExtName, True);
    reg.WriteString('', ExtName + 'file');
    reg.CloseKey;
    reg.CreateKey(ExtName + 'file');
    reg.OpenKey(ExtName + 'file\DefaultIcon', True);
    reg.WriteString('', AppName + ',0');
    reg.CloseKey;
    reg.OpenKey(ExtName + 'file\shell\open\command', True);
    reg.WriteString('', AppName + ' "%1"');
    reg.CloseKey;
  finally
    reg.Free;
  end;
  SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;
{$ENDIF}
var
   reg: TRegistry;
       
begin
  {$IFDEF WINDOWS}
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_CLASSES_ROOT;
    if not reg.KeyExists('ext' + 'file\shell\open\command') then
      RegisterFileType('ext', ExtractFilePath(Application.ExeName) + 'my_app.exe');
  finally
    reg.Free;
  end;
 
 if ParamCount > 0 then
  begin
    s := ParamStr(1);
    if ExtractFileExt(s) = '.ext' then
      LoadFile(s);
  end;
  {$ENDIF}

See also

If this component for some reason does not work for you, or you need to run it as administrator for all users without elevating your application privileges, an Inno Setup Script may fit your needs best.