improve start on boot (#313)

This commit is contained in:
AmirHossein Abdolmotallebi 2024-12-21 17:54:13 +03:30 committed by GitHub
parent 3a9d1c22f2
commit 8a24d5e06d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 61 additions and 62 deletions

View File

@ -9,6 +9,7 @@ import com.abdownloadmanager.desktop.utils.*
import com.abdownloadmanager.desktop.utils.singleInstance.* import com.abdownloadmanager.desktop.utils.singleInstance.*
import com.abdownloadmanager.integration.Integration import com.abdownloadmanager.integration.Integration
import com.abdownloadmanager.utils.DownloadSystem import com.abdownloadmanager.utils.DownloadSystem
import com.sun.jna.platform.win32.Advapi32Util
import ir.amirab.util.platform.Platform import ir.amirab.util.platform.Platform
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import okio.Path.Companion.toOkioPath import okio.Path.Companion.toOkioPath

View File

@ -196,10 +196,8 @@ val startUpModule = module {
single { single {
Startup.getStartUpManagerForDesktop( Startup.getStartUpManagerForDesktop(
name = AppInfo.name, name = AppInfo.name,
path = AppInfo.exeFile?.let { exeFile -> path = AppInfo.exeFile,
"$exeFile ${AppArguments.Args.BACKGROUND}" args = listOf(AppArguments.Args.BACKGROUND),
},
jar = false,
) )
} }
} }

View File

@ -3,4 +3,6 @@ plugins {
} }
dependencies { dependencies {
implementation(project(":shared:utils")) implementation(project(":shared:utils"))
// for windows, we use registry
implementation(libs.jna.platform)
} }

View File

@ -1,11 +1,22 @@
package ir.amirab.util.startup package ir.amirab.util.startup
abstract class AbstractStartupManager( abstract class AbstractStartupManager(
val isJar: Boolean,
val name: String, val name: String,
val path: String, val path: String,
val args: List<String>,
) { ) {
@Throws(Exception::class) @Throws(Exception::class)
abstract fun install() abstract fun install()
abstract fun uninstall() abstract fun uninstall()
fun getExecutableWithArgs(): String {
return buildList {
add(path.quoted())
addAll(args)
}.joinToString(" ")
}
private fun String.quoted(): String {
return "\"$this\""
}
} }

View File

@ -3,11 +3,11 @@ package ir.amirab.util.startup
class HeadlessStartup( class HeadlessStartup(
name: String, name: String,
path: String, path: String,
isJar: Boolean = false, args: List<String>,
) : AbstractStartupManager( ) : AbstractStartupManager(
name = name, name = name,
path = path, path = path,
isJar = isJar args = args,
) { ) {
@Throws(Exception::class) @Throws(Exception::class)
override fun install() { override fun install() {

View File

@ -7,9 +7,11 @@ import java.io.PrintWriter
class MacOSStartup( class MacOSStartup(
name: String, name: String,
path: String, path: String,
isJar: Boolean, args: List<String>,
) : AbstractStartupManager( ) : AbstractStartupManager(
path = path, name = name, isJar = isJar, path = path,
name = name,
args = args,
) { ) {
private fun getFile(): File { private fun getFile(): File {
if (!launchAgentsDir.exists()) { if (!launchAgentsDir.exists()) {
@ -28,11 +30,7 @@ class MacOSStartup(
out.println("\t<string>" + super.name + "</string>") out.println("\t<string>" + super.name + "</string>")
out.println("\t<key>ProgramArguments</key>") out.println("\t<key>ProgramArguments</key>")
out.println("\t<array>") out.println("\t<array>")
if (isJar) { out.println("\t\t<string>" + getExecutableWithArgs() + "</string>")
out.println("\t\t<string>java</string>")
out.println("\t\t<string>-jar</string>")
}
out.println("\t\t<string>" + super.path + "</string>")
out.println("\t</array>") out.println("\t</array>")
out.println("\t<key>RunAtLoad</key>") out.println("\t<key>RunAtLoad</key>")
out.println("\t<true/>") out.println("\t<true/>")

View File

@ -7,11 +7,14 @@ object Startup {
* Add file to startup * Add file to startup
* @param name Name of key/file * @param name Name of key/file
* @param path Path to file * @param path Path to file
* @param jar If file should be executed by the JVM
* @throws Exception * @throws Exception
*/ */
@Throws(Exception::class) @Throws(Exception::class)
fun getStartUpManagerForDesktop(name: String, path: String?, jar: Boolean = false): AbstractStartupManager { fun getStartUpManagerForDesktop(
name: String,
path: String?,
args: List<String>,
): AbstractStartupManager {
if (path==null){ if (path==null){
//there is no installation path provided so we use no-op //there is no installation path provided so we use no-op
return noImplStartUpManager() return noImplStartUpManager()
@ -20,18 +23,19 @@ object Startup {
val startup=when (os) { val startup=when (os) {
Platform.Desktop.Linux -> { Platform.Desktop.Linux -> {
if (Utils.isHeadless) { if (Utils.isHeadless) {
HeadlessStartup(name, path, jar) HeadlessStartup(name, path, args)
} else { } else {
UnixXDGStartup(name, path, jar) UnixXDGStartup(name, path, args)
} }
} }
Platform.Desktop.MacOS -> MacOSStartup(name, path, jar)
Platform.Desktop.Windows -> WindowsStartup(name, path, jar) Platform.Desktop.MacOS -> MacOSStartup(name, path, args)
Platform.Desktop.Windows -> WindowsStartup(name, path, args)
Platform.Android -> error("this code should not be called in android") Platform.Android -> error("this code should not be called in android")
} }
return startup return startup
} }
private fun noImplStartUpManager(): HeadlessStartup { private fun noImplStartUpManager(): HeadlessStartup {
return HeadlessStartup("","",false) return HeadlessStartup("", "", emptyList())
} }
} }

View File

@ -5,38 +5,32 @@ import java.io.FileWriter
import java.io.PrintWriter import java.io.PrintWriter
class UnixXDGStartup( class UnixXDGStartup(
name:String, name: String,
path: String, path: String,
isJar:Boolean=false args: List<String>,
) : AbstractStartupManager( ) : AbstractStartupManager(
name = name, name = name,
path = path, path = path,
isJar = isJar args = args,
) { ) {
private fun getAutoStartFile(): File { private fun getAutoStartFile(): File {
if (!autostartDir.exists()) { if (!autostartDir.exists()) {
autostartDir.mkdirs() autostartDir.mkdirs()
} }
return File(autostartDir, super.name + ".desktop") return File(autostartDir, this.name + ".desktop")
} }
@Throws(Exception::class) @Throws(Exception::class)
override fun install() { override fun install() {
val out = PrintWriter(FileWriter(getAutoStartFile())) val out = PrintWriter(FileWriter(getAutoStartFile()))
out.println("[Desktop Entry]") out.println("[Desktop Entry]")
out.println("Type=Application") out.println("Type=Application")
out.println("Name=" + super.name) out.println("Name=" + this.name)
if (isJar) { out.println("Exec=" + getExecutableWithArgs())
out.println("Exec=java -jar '" + super.path + "'")
} else {
out.println("Exec=" + super.path)
}
out.println("Terminal=false") out.println("Terminal=false")
out.println("NoDisplay=true") out.println("NoDisplay=true")
out.close() out.close()
val cmd = arrayOf("chmod", "+x", super.path)
Runtime.getRuntime().exec(cmd)
} }
override fun uninstall() { override fun uninstall() {

View File

@ -7,11 +7,6 @@ import java.io.File
import java.io.InputStreamReader import java.io.InputStreamReader
object Utils { object Utils {
val jarFile: File
get() = File(
Utils::class.java.protectionDomain.codeSource.location.path.replace("%20", " ").replace("file:", "")
)
@get:Throws(Exception::class) @get:Throws(Exception::class)
val isRoot: Boolean val isRoot: Boolean
get() = Platform.getCurrentPlatform() !== Platform.Desktop.Windows && BufferedReader( get() = Platform.getCurrentPlatform() !== Platform.Desktop.Windows && BufferedReader(

View File

@ -1,41 +1,37 @@
package ir.amirab.util.startup package ir.amirab.util.startup
import com.sun.jna.platform.win32.Advapi32Util
import com.sun.jna.platform.win32.WinReg
class WindowsStartup( class WindowsStartup(
name: String, name: String,
path: String, path: String,
isJar: Boolean = false, args: List<String>,
) : AbstractStartupManager( ) : AbstractStartupManager(
name = name, name = name,
path = path, path = path,
isJar = isJar args = args
) { ) {
private fun getData(): String {
return if (isJar) {
val javaHome = System.getProperty("java.home") + "\\bin\\javaw.exe"
"$javaHome -jar \"$path\""
} else {
super.path
}
}
@Throws(Exception::class) @Throws(Exception::class)
override fun install() { override fun install() {
val data=getData() val data = getExecutableWithArgs()
Advapi32Util.registrySetStringValue(
Runtime.getRuntime().exec( WinReg.HKEY_CURRENT_USER,
arrayOf("reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\", "/v", super.name, "/t", "Software\\Microsoft\\Windows\\CurrentVersion\\Run",
"REG_SZ", "/d", data, "/f" this.name,
) data
) )
} }
override fun uninstall() { override fun uninstall() {
Runtime.getRuntime().exec( try {
arrayOf( Advapi32Util.registryDeleteValue(
"reg", "delete", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\", WinReg.HKEY_CURRENT_USER,
"/v", super.name, "/f", "Software\\Microsoft\\Windows\\CurrentVersion\\Run",
this.name,
) )
) } catch (e: Exception) {
e.printStackTrace()
}
} }
} }