Link to home
Start Free TrialLog in
Avatar of new_x
new_x

asked on

Finding associated program..


You know when we double-click a file in the explorer, it finds the associated application, runs it, and gives the file as an argument to the app.


 I know that it uses the information under HKEY_CLASSES_ROOT. But when I want to do the same thing in a Delphi program, everything goes well with 98 or 95 but there are problems while running on NT...(may be beacuse of user rights..)

  How can I read these values while I am logged on as user not an administrator..

Thanx.


Avatar of simonet
simonet
Flag of Brazil image

Can you give us a more detailed description of the problem under Windows NT?

How did you create the file association for your application's file type?

Alex
Athena's Place: http://www.bhnet.com.br/~simonet
Avatar of philipleighs
philipleighs

You can use FindExecutable.

Cheers,
Phil.

Hi,

I couldn´t get where is the problem. In the file association, in getting the ParamStr parameter, etc...

Could you give more details ?

Thanks,
Itamar
If you want to use the registry instead of FindExecutable, then use TRegistry.OpenKeyReadOnly instead of TRegistry.OpenKey.

(You need D4).

OpenKeyReadOnly works on HKEY_LOCAL_MACHINE if you are a guest on NT. OpenKey(..., false) does not!

I still don't understand what you're trying to achieve. If you want to run a file/open using its default application, use ShellExecute or ShellExecuteEx. If you want to know the description of the file type associated with a certain extension, you can use SHGetFileInfo.

I still don't see why you'd need the Registry for any of these tasks. Do you mind explaining what exactly you're trying to do?

Alex
Athena's Place: http://www.bhnet.com.br/~simonet
Alex is right. If possible, you should use ShellExecute(Ex). If you really want to KNOW which exe belongs to a specific file, you can use this one (Phil already suggested it):

uses shellAPI;

function FindExecutable(filename: string) : string;
var arrch : array [0..MAX_PATH] of char;
begin
  if shellAPI.FindExecutable(pchar(ExtractFileName(filename)),pchar(ExtractFilePath(filename)),arrch)>32 then
       result:=arrch
  else result:=filename;
end;

Regards, Madshi.

new_x

Here is a way to do under all platforms(it's form the borland site)...

uses
                       {$IFDEF WIN32}
                         Registry; {We will get it from the registry}
                       {$ELSE}
                         IniFiles; {We will get it from the win.ini file}
                       {$ENDIF}

                       {$IFNDEF WIN32}
                         const MAX_PATH = 144;
                       {$ENDIF}

                       function GetProgramAssociation (Ext : string) : string;
                       var
                       {$IFDEF WIN32}
                         reg: TRegistry;
                         s : string;
                       {$ELSE}
                         WinIni : TIniFile;
                         WinIniFileName : array[0..MAX_PATH] of char;
                         s : string;
                       {$ENDIF}
                       begin
                       {$IFDEF WIN32}
                         s := '';
                         reg := TRegistry.Create;
                         reg.RootKey := HKEY_CLASSES_ROOT;
                         if reg.OpenKey('.' + ext + '\shell\open\command',
                                        false) <> false then begin
                         {The open command has been found}
                           s := reg.ReadString('');
                           reg.CloseKey;
                         end else begin
                         {perhaps thier is a system file pointer}
                           if reg.OpenKey('.' + ext,
                                          false) <> false then begin
                             s := reg.ReadString('');
                             reg.CloseKey;
                             if s <> '' then begin
                            {A system file pointer was found}
                               if reg.OpenKey(s + '\shell\open\command',
                                              false) <> false then
                            {The open command has been found}
                                 s := reg.ReadString('');
                               reg.CloseKey;
                             end;
                           end;
                         end;
                        {Delete any command line, quotes and spaces}
                         if Pos('%', s) > 0 then
                           Delete(s, Pos('%', s), length(s));
                         if ((length(s) > 0) and
                             (s[1] = '"')) then
                           Delete(s, 1, 1);
                         if ((length(s) > 0) and
                             (s[length(s)] = '"')) then
                           Delete(s, Length(s), 1);
                         while ((length(s) > 0) and
                                ((s[length(s)] = #32) or
                                 (s[length(s)] = '"'))) do
                           Delete(s, Length(s), 1);
                       {$ELSE}
                         GetWindowsDirectory(WinIniFileName, sizeof(WinIniFileName));
                         StrCat(WinIniFileName, '\win.ini');
                         WinIni := TIniFile.Create(WinIniFileName);
                         s := WinIni.ReadString('Extensions',
                                                 ext,
                                                 '');
                         WinIni.Free;
                        {Delete any command line}
                         if Pos(' ^', s) > 0 then
                           Delete(s, Pos(' ^', s), length(s));
                        {$ENDIF}
                         result := s;
                       end;

                       procedure TForm1.Button1Click(Sender: TObject);
                       begin
                         ShowMessage(GetProgramAssociation('gif'));
                       end;

Later
BoRiS
One thing about FindExecutable is that it can only be used on files that exist.

You can't do this:
FindExecutable(..., '*.hcp', ...)
It will fail.

So if you're writing a WinZip style program then FindExecutable will be no good to you.

Maybe this little tidbit will save you some time going through all the options.

Cheers,
Phil.


Hi Phil, I noticed one strange thing: FindExecutable works NOT with "*.bmp", but it works well with "*.txt" on my computer. That's quite strange, isn't it!?

Regards, Madshi.
Yeah, that is wierd.
I tried it on mine, neither *.bmp nor *.txt worked!
>>
SetLength(s, MAX_PATH);
if FindExecutable('*.bmp', nil, PChar(s)) > 32 then
  ShowMessage(PChar(s));
<<

Maybe SHGetFileInfo does a better job.
I haven't tried.

Cheers,
Phil.

new_x

Helloooo !!!!
Maybe "*.txt" did work but "*.bmp" not because in there current directory there WAS a file with the .txt extension but there WASN'T any with ".bmp". Just a thought.

Rico
Rico, yep, sounds logical...
Avatar of new_x

ASKER

Hi al


  I want to asscociate my own program with a file extension, To do that I think I have to write some data under HKEY_CLASSES root, so then when somebody clicks a file of with that extension myprogram will run.

  For instance I want to make  'tlx' extension  associated with my App, so to make this change I have to create the key HKEY_CLASSES_ROOT\.tlx and write some data under it . For intance in my registry under HKEY_CLASSES _ROOT there is a key
 .bmp , under this key the string (default) 'ACDC_BMP ' exists.
 There is also another key with the name  ACDC_BMP.
Under ACDC_BMP\Shell\open\command the associated app name exists.
  But under NT, there are some restrictions when you read/write to registry . Am I wrong..
   

Thanx..


ASKER CERTIFIED SOLUTION
Avatar of simonet
simonet
Flag of Brazil image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of new_x

ASKER

I Thank you all

 



Avatar of new_x

ASKER


  I Thank you all