Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Putting shortcut into Startup Folder

Posted on 2002-04-08
13
Medium Priority
?
576 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

604 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