Page 1 of 2
How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 2:12 pm
by c4s
My program doesn't need an installation so the user can theoretically place the executable where he wants to. Many don't seem to know that they can autostart a program by placing a shortcut in the autostart folder. Since I'm getting more and more requests to add such a feature I'm asking myself how I could add an option for this while keeping it as "portable" as possible.
I know two ways of doing it. Which one would be the best or are there more?
- Automatically place a shortcut in the autostart folder that points to the current executable
- Create entry in the registry that points to the current executable
Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 3:12 pm
by eJan
Most of programs (Antivirus, Players, Audio Mixers..) use Registry autorun feature:
For current user:
Code: Select all
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
For all users:
Code: Select all
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 3:25 pm
by netmaestro
This is the method I use, code is by Joakim Christiansen. With this procedure all you need to do is implement a menu item for the user to check or clear "Start with Windows" and run this procedure with the state parameter set to 1 or 0. I use it in several of my programs and it's never given me any problems:
Code: Select all
Procedure StartWithWindows(State.b) ; by Joakim Christiansen
Protected Key.l = #HKEY_CURRENT_USER ;or #HKEY_LOCAL_MACHINE for every user on the machine
Protected Path.s = "Software\Microsoft\Windows\CurrentVersion\Run"
Protected Value.s = "GmailEnhancer" ;Change into the name of your program
Protected String.s = Chr(34)+ProgramFilename()+Chr(34) ;Path of your program
Protected CurKey.l
If State
RegCreateKey_(Key,@Path,@CurKey)
RegSetValueEx_(CurKey,@Value,0,#REG_SZ,@String,Len(String))
Else
RegOpenKey_(Key,@Path,@CurKey)
RegDeleteValue_(CurKey,@Value)
EndIf
RegCloseKey_(CurKey)
EndProcedure
Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 3:29 pm
by ts-soft
A Portable App should not use the registry! There is no uninstaller.
Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 4:23 pm
by c4s
ts-soft wrote:A Portable App should not use the registry! There is no uninstaller.
Yes, that is the intention of this thread. I'm asking which method is best for a portable application.
Currently I think it would be best to simply create a shortcut to the executable... What do you think?
@eJan & netmaestro
Honest question: Would you say a portable program should hassle with the registry?
Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 5:34 pm
by ts-soft
A real portable app starts from a memorystick or something else, so a autostart is useless,
but i think you didn't mean a portable app, you mean a "none usermode compatible" app

Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 6:21 pm
by utopiomania
A portable application could very well have an install/uninstall from a menu entry, so that you
could run the app from a memory stick and then decide to install/uninstall it locally from within
the application.
Besides this, a 'start with windows' registry entry would only work if the exe is on a drive that
is accessible to windows on startup, or, you need to install a local exe that will look for your
application on memorysticks after startup.
Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 7:27 pm
by c4s
I didn't mean that my program is just used on USB sticks etc.! I used the term "portable" to underline that my program doesn't need an installation. Probably most of the users still copy it somewhere on their disk and that's it. These are asking for a autostart feature because they don't know that it's already possible by copying a shortcut into the autostart folder.
The question to me is how I could give them the autostart feature they want to have.
Writing to the registry is generally less accepted - especially for a portable program. ALso it's much harder to edit or remove a registry entry compared to a shortcut. I'm still curious if there is a better solution for this.
Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 7:57 pm
by Trond
I recommend to create a shortcut in the autostart folder. Because it's simpler to remove from outside the program.
Re: How to add autostart feature for portable program?
Posted: Sun Mar 20, 2011 8:31 pm
by idle
To add to the start up menu.
Code: Select all
Procedure CreateShellLink(PATH$, LINK$, Argument$, DESCRIPTION$, WorkingDirectory$, ShowCommand.l, HotKey.l, IconFile$, IconIndexInFile.l)
Protected psl.IShellLinkA,ppf.IPersistFile,*mem,len,hres,res.s
CoInitialize_(0)
If CoCreateInstance_(?CLSID_ShellLink,0,1,?IID_IShellLink,@psl.IShellLinkA) = 0
;Set_ShellLink_preferences:
psl\SetPath(PATH$)
psl\SetArguments(Argument$)
psl\SetWorkingDirectory(WorkingDirectory$)
psl\SetDescription(DESCRIPTION$)
psl\SetShowCmd(ShowCommand)
psl\SetHotkey(HotKey)
psl\SetIconLocation(IconFile$, IconIndexInFile)
;ShellLink_SAVE:
If psl\QueryInterface(?IID_IPersistFile,@ppf.IPersistFile) = 0
*mem = AllocateMemory(1000)
len = MultiByteToWideChar_(#CP_ACP, 0, LINK$, -1, *mem, 1000)
res.s = PeekS(*mem,len,#PB_Unicode)
hres = ppf\Save(res,#True)
FreeMemory(*mem)
ppf\Release()
EndIf
psl\Release()
EndIf
CoUninitialize_()
ProcedureReturn hres ! 1
DataSection
CLSID_ShellLink:
; 00021401-0000-0000-C000-000000000046
Data.l $00021401
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
IID_IShellLink:
; DEFINE_SHLGUID(IID_IShellLinkA,0x000214EEL, 0, 0);
; C000-000000000046
Data.l $000214EE
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
IID_IPersistFile:
; 0000010b-0000-0000-C000-000000000046
Data.l $0000010b
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46
EndDataSection
EndProcedure
Procedure.s GetSpecialFolderLocation(Value.l)
Protected Folder_ID,SpecialFolderLocation.s
If SHGetSpecialFolderLocation_(0, Value, @Folder_ID) = 0
SpecialFolderLocation = Space(#MAX_PATH*2)
SHGetPathFromIDList_(Folder_ID, @SpecialFolderLocation)
If SpecialFolderLocation
If Right(SpecialFolderLocation, 1) <> "\"
SpecialFolderLocation + "\"
EndIf
EndIf
CoTaskMemFree_(Folder_ID)
EndIf
ProcedureReturn SpecialFolderLocation.s
EndProcedure
#CSIDL_STARTUP = $7
#CSIDL_APPDATA = $1A
Procedure AddtoStartMenu()
Protected tpath.s = GetSpecialFolderLocation(#CSIDL_STARTUP) + "MyApp.lnk"
CreateShellLink(ProgramFilename(),tpath,"","MyApp","",0,0,ProgramFilename(),0)
EndProcedure
Re: How to add autostart feature for portable program?
Posted: Mon Mar 21, 2011 8:47 am
by Joakim Christiansen
idle wrote:To add to the start up menu.
I was about to post the same code here but when I tested it it wouldn't work on the XP SP3 computer I used.
Did you test it? (you probably did)
netmaestro
c4s
I think option 1 is the best for a portable app.
Re: How to add autostart feature for portable program?
Posted: Mon Mar 21, 2011 12:18 pm
by c4s
@idle
Thanks for the code.
@Joakim
I just tested idle's code on XP SP3 and it works. Note that you have to
enable Unicode.
I think this code works with both Ascii and Unicode:
Code: Select all
Macro DEFINE_GUID(Name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
CompilerIf Defined(Name, #PB_Variable)
If SizeOf(Name) = SizeOf(GUID)
Name\Data1 = l
Name\Data2 = w1
Name\Data3 = w2
Name\Data4[0] = b1
Name\Data4[1] = b2
Name\Data4[2] = b3
Name\Data4[3] = b4
Name\Data4[4] = b5
Name\Data4[5] = b6
Name\Data4[6] = b7
Name\Data4[7] = b8
EndIf
CompilerEndIf
EndMacro
Procedure ShortcutCreate(Path.s, Link.s, WorkingDir.s="", Argument.s="", ShowCommand=#SW_SHOWNORMAL, Description.s="", HotKey=#Null, IconFile.s="|", IconIndex=0)
; Path: "C:\PureBasic\purebasic.exe"
; Link: "C:\Documents and Settings\User\Desktop\PureBasic.lnk"
; WorkingDir: "C:\PureBasic\"
; Argument: "%1"
; ShowCommand: #SW_SHOWNORMAL, #SW_SHOWMAXIMIZED or #SW_SHOWMINIMIZED
; Description: "Start PureBasic"
; HotKey: Shortcut of keys for the link
; IconFile: "C:\PureBasic\purebasic.exe"
; IconIndex: 0
Protected CLSID_ShellLink.GUID, IID_IShellLink.GUID, IID_IPersistFile.GUID
CompilerIf #PB_Compiler_Unicode
Protected psl.IShellLinkW
CompilerElse
Protected psl.IShellLinkA
CompilerEndIf
Protected ppf.IPersistFile
Protected Result = #False
DEFINE_GUID(CLSID_ShellLink, $00021401, $0000, $0000, $C0, $00, $00, $00, $00, $00, $00, $46)
CompilerIf #PB_Compiler_Unicode
DEFINE_GUID(IID_IShellLink, $000214F9, $0000, $0000, $C0, $00, $00, $00, $00, $00, $00, $46)
CompilerElse
DEFINE_GUID(IID_IShellLink, $000214EE, $0000, $0000, $C0, $00, $00, $00, $00, $00, $00, $46)
CompilerEndIf
DEFINE_GUID(IID_IPersistFile, $0000010B, $0000, $0000, $C0, $00, $00, $00, $00, $00, $00, $46)
If Len(WorkingDir) = 0 : WorkingDir = GetPathPart(Path) : EndIf
If IconFile = "|" : IconFile = Path : EndIf
CoInitialize_(0)
If CoCreateInstance_(@CLSID_ShellLink, 0, 1, @IID_IShellLink, @psl) = #S_OK
With psl
\SetPath(Path)
\SetArguments(Argument)
\SetWorkingDirectory(WorkingDir)
\SetDescription(Description)
\SetShowCmd(ShowCommand)
\SetHotkey(HotKey)
\SetIconLocation(IconFile, IconIndex)
EndWith
If psl\QueryInterface(@IID_IPersistFile, @ppf) = #S_OK
If ppf\Save(Link, #True) = #S_OK
Result = #True
EndIf
ppf\Release()
EndIf
psl\Release()
EndIf
CoUninitialize_()
ProcedureReturn Result
EndProcedure
Now I'm not sure anymore if an option for creating a program shortcut in the autostart folder is useful at all. Maybe I'm just going to add a text that explains it...
Re: How to add autostart feature for portable program?
Posted: Mon Mar 21, 2011 4:22 pm
by idle
Joakim Christiansen wrote:idle wrote:To add to the start up menu.
I was about to post the same code here but when I tested it it wouldn't work on the XP SP3 computer I used.
Did you test it? (you probably did)
No I didn't test it as posted, my VM wasn't running at the time.
Maybe you'd be better off using the Registry function with the RunOnce key, you will need to write it every time your app quits, since it's a temporary registry entry.
Re: How to add autostart feature for portable program?
Posted: Mon Mar 21, 2011 4:38 pm
by greyhoundcode
Although you don't mean portable in the sense of running exclusively off USB sticks or similar, in those instances where an app is running from removable media one could make use of an auto-run batch script.
Perhaps a complete and non-Registry dependent solution would somehow detect whether it is on the hard-drive or a stick and then make use of an auto run script or shortcuts as appropriate.
Re: How to add autostart feature for portable program?
Posted: Mon Mar 21, 2011 5:23 pm
by idle
The only problem with using autorun is that it's disabled for removable media by default but, it will at least pop up with your app as the default choice highlighting your icon, it just won't automatically start unless it's been enabled by the system policy, think the default behavior was changed in XP SP2 or maybe even earlier.
Also if you use any registry or start menu stuff and the apps on removable media you can't be sure it's going to have the same drive label next time round.
So maybe giving users the choice to create a portable version on a usb with Autorun or add to StartUpMenu for this machine or set the runonce key each time your app quits.
as an example of creating a portable version of your app on a USB
Not tested!
save this autorun.inf
[autorun]
OPEN=MyApp.exe
ICON=MyApp.ico
ACTION=MyApp
LABEL=MyApp
Code: Select all
Procedure MakePortable(MyApp.s)
strm.s = "Select the USB drive to make " + MyApp + " portable on"
MessageRequester(MyApp,strm)
dir.s = PathRequester(strm,"*.*")
If dir <> ""
CopyFile(MyApp + ".exe",dir+ MyApp + ".exe")
fn = CreateFile(#PB_Any,dir+"autorun.inf")
If fn
WriteData(fn,?auto,?eauto-?auto)
CloseFile(fn)
EndIf
fn = CreateFile(#PB_Any,dir+MyApp+".ico")
If fn
WriteData(fn,?ico,?eico-?ico)
CloseFile(fn)
SetFileAttributes(dir+MyApp+".ico",#PB_FileSystem_Hidden)
EndIf
EndIf
DataSection
Ico: IncludeBinary "icon.ico"
eIco:
Auto:IncludeBinary "autorun.inf"
eAuto:
EndDataSection
EndProcedure
;Save as autorun.inf
;[autorun]
;OPEN=MyApp.exe
;ICON=MyApp.ico
;ACTION=MyApp
;LABEL=MyApp