How to add autostart feature for portable program?

Everything else that doesn't fall into one of the other PB categories.
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

How to add autostart feature for portable program?

Post 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
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
eJan
Enthusiast
Enthusiast
Posts: 366
Joined: Sun May 21, 2006 11:22 pm
Location: Sankt Veit am Flaum

Re: How to add autostart feature for portable program?

Post 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
Image
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: How to add autostart feature for portable program?

Post 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 
BERESHEIT
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: How to add autostart feature for portable program?

Post by ts-soft »

A Portable App should not use the registry! There is no uninstaller.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: How to add autostart feature for portable program?

Post 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?
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: How to add autostart feature for portable program?

Post 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 :mrgreen:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Re: How to add autostart feature for portable program?

Post 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.
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: How to add autostart feature for portable program?

Post 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.
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: How to add autostart feature for portable program?

Post by Trond »

I recommend to create a shortcut in the autostart folder. Because it's simpler to remove from outside the program.
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: How to add autostart feature for portable program?

Post 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   

Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Joakim Christiansen
Addict
Addict
Posts: 2452
Joined: Wed Dec 22, 2004 4:12 pm
Location: Norway
Contact:

Re: How to add autostart feature for portable program?

Post 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 8)

c4s
I think option 1 is the best for a portable app.
I like logic, hence I dislike humans but love computers.
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: How to add autostart feature for portable program?

Post 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...
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: How to add autostart feature for portable program?

Post 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.
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
greyhoundcode
Enthusiast
Enthusiast
Posts: 112
Joined: Sun Dec 30, 2007 7:24 pm

Re: How to add autostart feature for portable program?

Post 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.
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: How to add autostart feature for portable program?

Post 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

Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply