Skip to content

Commit

Permalink
Fix #1449 Windows 上用快捷方式打开时, 可能会无法安装自动更新
Browse files Browse the repository at this point in the history
  • Loading branch information
Him188 committed Feb 1, 2025
1 parent 80092b7 commit deaa5a1
Showing 1 changed file with 48 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2024 OpenAni and contributors.
* Copyright (C) 2024-2025 OpenAni and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license, which can be found at the following link.
Expand All @@ -9,6 +9,10 @@

package me.him188.ani.app.tools.update

import com.sun.jna.Native
import com.sun.jna.platform.win32.Kernel32
import com.sun.jna.platform.win32.WinDef
import com.sun.jna.win32.W32APIOptions
import me.him188.ani.app.platform.ContextMP
import me.him188.ani.app.platform.FileOpener
import me.him188.ani.utils.io.SystemPath
Expand Down Expand Up @@ -67,7 +71,7 @@ object WindowsUpdateInstaller : DesktopUpdateInstaller {

override fun install(file: SystemPath, context: ContextMP): InstallationResult {
logger.info { "Installing update for Windows" }
val appDir = File(System.getProperty("user.dir") ?: throw IllegalStateException("Cannot get app directory"))
val appDir = getExecutableDirectory()
logger.info { "Current app dir: ${appDir.absolutePath}" }
if (!appDir.resolve("Ani.exe").exists()) {
logger.info { "Current app dir does not have 'Ani.exe'. Fallback to manual update" }
Expand Down Expand Up @@ -107,6 +111,48 @@ object WindowsUpdateInstaller : DesktopUpdateInstaller {
}
}

@Suppress("FunctionName")
interface MyKernel32 : Kernel32 {

/**
* Retrieves the fully qualified path for the file that contains the specified module.
* If this parameter is null, GetModuleFileName retrieves the path of the executable file
* of the current process.
*
* @param hModule A handle to the loaded module whose path is being requested. If null,
* this function returns the path of the current process's executable.
* @param lpFilename A buffer that receives the fully qualified path of the module.
* @param nSize The size of the lpFilename buffer, in characters.
* @return The length of the string copied to lpFilename.
*
* @see <a href="https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamew">
* Microsoft Docs: GetModuleFileNameW</a>
*/
fun GetModuleFileNameW(
hModule: WinDef.HMODULE?,
lpFilename: CharArray,
nSize: Int
): Int

companion object {
val INSTANCE: MyKernel32 = Native.load(
"kernel32",
MyKernel32::class.java,
W32APIOptions.DEFAULT_OPTIONS,
)
}
}

/**
* Returns the absolute directory containing the actual .exe on Windows.
*/
fun getExecutableDirectory(): File {
val buffer = CharArray(1024)
val length = MyKernel32.INSTANCE.GetModuleFileNameW(null, buffer, buffer.size)
val fullPath = String(buffer, 0, length)
return File(fullPath).parentFile
}

@Language("cmd")
private fun getInstallerScript(
zipFile: File,
Expand Down

0 comments on commit deaa5a1

Please sign in to comment.