Solved

Putting shortcut into Startup Folder

Posted on 2002-04-08
13
562 Views
Last Modified: 2010-04-04
I need to create a link for an application to start in the StartUp Folder for both win9x & NT from a Delphi Application. Does someone know how to do this from Delphi for both operating systems?
0
Comment
Question by:skynergy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 4
13 Comments
 
LVL 17

Expert Comment

by:inthe
ID: 6926055
this should work:

uses
   ActiveX,ShlObj;

function MakeLinks(AppName: String; Startmenu, Desktop: Boolean): Boolean;
const
   ShellFolderKey =
'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders';
   DesktopKey = 'Desktop';
   ProgramsKey = 'Startup'; //for startup menu
 //ProgramsKey = 'Programs';  //for programs menu

var
   tmp: array[0..MAX_PATH] of Char;
   MainKey: HKEY;
   ValLen: DWORD;
   SL: IShellLink;
   PF: IPersistFile;
   LnkName: WideString;
begin
   Result := false;
   if RegOpenKeyEx(HKEY_CURRENT_USER, PChar(ShellFolderKey), 0,
    KEY_QUERY_VALUE, MainKey) = ERROR_SUCCESS then begin
     try
       if CoInitialize(nil) <> S_OK then exit;
       try
         if Desktop then begin
           ValLen := MAX_PATH;
           RegQueryValueEx(MainKey, PChar(DesktopKey), nil, nil, @tmp,
@ValLen);
           if CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER,
             IShellLink, SL) <> S_OK then exit;
           PF := SL as IPersistFile;
           if SL.SetPath(PChar(AppName)) <> S_OK then exit;
           if SL.SetWorkingDirectory(PChar(ExtractFilePath(AppName))) <>
S_OK then exit;
           LnkName := tmp + String('\') +
ChangeFileExt(ExtractFileName(AppName), '') + '.lnk';
           PF.Save(PWideChar(LnkName), True);
         end;
         if Startmenu then begin
           ValLen := MAX_PATH;
           RegQueryValueEx(MainKey, PChar(ProgramsKey), nil, nil, @tmp,
@ValLen);
           if CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER,
             IShellLink, SL) <> S_OK then exit;
           PF := SL as IPersistFile;
           if SL.SetPath(PChar(AppName)) <> S_OK then exit;
           if SL.SetWorkingDirectory(PChar(ExtractFilePath(AppName))) <>
S_OK then exit;
           LnkName := tmp + String('\') +
ChangeFileExt(ExtractFileName(AppName), '') + '.lnk';
           PF.Save(PWideChar(LnkName), True);
         end;
         Result := True;
       finally
         CoUninitialize;
       end;
     finally
       RegCloseKey(MainKey);
     end;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
makelinks('c:\myfile.txt',true,false);
end;
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6926589
3234 Adding shortcuts to Win95/WinNT4 Desktop/StartMenu

This sample project demonstrates an easy way to add shortcuts to
your Windows 95 or Windows NT 4.0 desktop or start menu.

1. Launch Delphi 3.

2. In a new project, drop a TButton on the form (make sure it's
   called Button1). Then double click on Button1. Now you can go
   ahead and directly replace the code for Unit1 with the code for
   Unit1 below.

The program will set up a shortcut either (see the code) on the
desktop or on the start menu. The shortcut will be called FooBar
and it will open up your AUTOEXEC.BAT in NOTEPAD when executed.

It will read the value of the "Desktop" and "Start Menu" strings
from the registry key named (under HKEY_CURRENT_USER):

 Software\MicroSoft\Windows\CurrentVersion\Explorer\Shell Folders

--------------
The Unit1 unit
--------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses
  ShlObj, ActiveX, ComObj, Registry;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyObject  : IUnknown;
  MySLink   : IShellLink;
  MyPFile   : IPersistFile;
  FileName  : String;
  Directory : String;
  WFileName : WideString;
  MyReg     : TRegIniFile;
begin
  MyObject := CreateComObject(CLSID_ShellLink);
  MySLink := MyObject as IShellLink;
  MyPFile := MyObject as IPersistFile;
  FileName := 'NOTEPAD.EXE';
  with MySLink do begin
    SetArguments('C:\AUTOEXEC.BAT');
    SetPath(PChar(FileName));
    SetWorkingDirectory(PChar(ExtractFilePath(FileName)));
  end;
  MyReg := TRegIniFile.Create(
    'Software\MicroSoft\Windows\CurrentVersion\Explorer');

// Use the next line of code to put the shortcut on your desktop
  Directory := MyReg.ReadString('Shell Folders','Desktop','');

// Use the next three lines to put the shortcut on your start menu
//  Directory := MyReg.ReadString('Shell Folders','Start Menu','')+
//      '\Whoa!';
//  CreateDir(Directory);

  WFileName := Directory+'\FooBar.lnk';
  MyPFile.Save(PWChar(WFileName),False);
  MyReg.Free;
end;

end.

        TI
0
 

Author Comment

by:skynergy
ID: 6927398
Hi inthe! Thanx for the great code. Additional question that I forgot to ask. How would one add a parameter for the LNK?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 17

Expert Comment

by:inthe
ID: 6927445
hi,
to add parameters to it you can do like below where ive added the setarguments() call:

uses
  ActiveX,ShlObj;

function MakeLinks(AppName,args: String; Startmenu, Desktop: Boolean): Boolean;
const
  ShellFolderKey =
'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders';
  DesktopKey = 'Desktop';
  ProgramsKey = 'Startup'; //for startup menu
//ProgramsKey = 'Programs';  //for programs menu

var
  tmp: array[0..MAX_PATH] of Char;
  MainKey: HKEY;
  ValLen: DWORD;
  SL: IShellLink;
  PF: IPersistFile;
  LnkName: WideString;
begin
  Result := false;
  if RegOpenKeyEx(HKEY_CURRENT_USER, PChar(ShellFolderKey), 0,
   KEY_QUERY_VALUE, MainKey) = ERROR_SUCCESS then begin
    try
      if CoInitialize(nil) <> S_OK then exit;
      try
        if Desktop then begin
          ValLen := MAX_PATH;
          RegQueryValueEx(MainKey, PChar(DesktopKey), nil, nil, @tmp,
@ValLen);
          if CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER,
            IShellLink, SL) <> S_OK then exit;
          PF := SL as IPersistFile;
          if SL.SetPath(PChar(AppName)) <> S_OK then exit;
          if SL.SetWorkingDirectory(PChar(ExtractFilePath(AppName))) <>
S_OK then exit;
          LnkName := tmp + String('\') +
ChangeFileExt(ExtractFileName(AppName), '') + '.lnk';
          PF.Save(PWideChar(LnkName), True);
        end;
        if Startmenu then begin
          ValLen := MAX_PATH;
          RegQueryValueEx(MainKey, PChar(ProgramsKey), nil, nil, @tmp,
@ValLen);
          if CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER,
            IShellLink, SL) <> S_OK then exit;
          PF := SL as IPersistFile;
          sl.SetArguments(pchar(args));
          if SL.SetPath(PChar(AppName)) <> S_OK then exit;
          if SL.SetWorkingDirectory(PChar(ExtractFilePath(AppName))) <>
S_OK then exit;
          LnkName := tmp + String('\') +
ChangeFileExt(ExtractFileName(AppName), '') + '.lnk';
          PF.Save(PWideChar(LnkName), True);
        end;
        Result := True;
      finally
        CoUninitialize;
      end;
    finally
      RegCloseKey(MainKey);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
makelinks('c:\test\project1.exe','hello',true,false);
end;


and to test it:

procedure TForm1.FormCreate(Sender: TObject);
begin
edit1.clear;
edit1.text := paramstr(1);
end;

you add the oncreate test on the same program just the first time you run it the edit should stay empty then second time when run from the startmenu the edit will contain hello
0
 
LVL 17

Expert Comment

by:inthe
ID: 6927450
actually should move this
sl.SetArguments(pchar(args));
to the next line so it is after appname has returned ok
0
 

Author Comment

by:skynergy
ID: 6927641
Why does my application exit at "if CoInitialize(nil) <> S_OK then exit;" and a new test application don't?
0
 

Author Comment

by:skynergy
ID: 6928022
Also how would I remove this shortcut again from Startup?
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6928210
Why not just use Borland recommended code as shown in ti 3234 above?
0
 

Author Comment

by:skynergy
ID: 6928487
Will I be able to remove the link as well? I am only interested in the Startup folder really.
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6929736
You can create the link wherever you want:

// Use the next line of code to put the shortcut in your startup folder
 Directory := MyReg.ReadString('Shell Folders','Startup','');

which just gets the startup folder from the reg and puts it in the String var, Directory.

Than later you can delete it as with any file:
DeleteFile(Directory+'\FooBar.lnk');
0
 
LVL 17

Accepted Solution

by:
inthe earned 100 total points
ID: 6930505
i had some code given from madshi which ive altered a little to only do startup dir and to give a uninstall option.
as it looks like it was originally based on borlands code you should give the points to steve ,no probs here with that :)


uses
Registry, ShlObj,ActiveX, ComObj;

procedure CreateShortcut(FileName,Args: string;uninstall : boolean);
var
LPUnknown : IUnknown;
pShlLnk : IShellLink;
pszFileName : IPersistFile;
Dir,LinkName : string;
FullPath : WideString;
R : TRegIniFile;
begin
LPUnknown := CreateComObject(CLSID_ShellLink);
pShlLnk := LPUnknown as IShellLink;
pszFileName := LPUnknown as IPersistFile;
pShlLnk.SetPath(PChar(FileName));
pShlLnk.SetArguments(PChar(Args));
R := TRegIniFile.Create('Software\MicroSoft\Windows\CurrentVersion\Explorer');
try
LinkName := ChangeFileExt(FileName, '.lnk');
LinkName := ExtractFileName(LinkName);
Dir := R.ReadString('Shell Folders', 'Startup', '');
if Dir <> '' then
begin
FullPath := Dir + '\' + LinkName;
if uninstall then
DeleteFile(FullPath)
else
pszFileName.Save(PWChar(FullPath), False);
end;
finally
R.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin //to install
CreateShortcut('c:\windows\notepad.exe','hello',false);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin//to uninstall
CreateShortcut('c:\windows\notepad.exe','hello',true);
end;
0
 

Author Comment

by:skynergy
ID: 6930539
Just want to thank you for all your help and the fact that you even gave me a simple procedure to implement. It saved me a lot of time and effort. Thanx to Steve too for helping us out! It's a pitty one can't split or share the points? Thanx guys!
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 6932543
:)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi IDE crash without error message ... 7 120
LAN or WAN ? 11 106
RESTRequest Parameter 4 54
Is there any way to treat Lock record in table with clientdataset? 3 32
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question