Solved

Putting shortcut into Startup Folder

Posted on 2002-04-08
13
561 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
  • 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…

831 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