Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xpack打包的软件卸载时会删除依赖的动态库原文件而不是安装目录下的文件 #5952

Closed
liuli-neko opened this issue Dec 10, 2024 · 13 comments
Labels
Milestone

Comments

@liuli-neko
Copy link

Xmake 版本

2.9.6

操作系统版本和架构

Windows 10 专业工作站版

描述问题

生成的安装脚本中依赖文件命令
SetOutPath "$InstDir\bin" File "/oname=libcrypto-1_1-x64.dll" "C:\Users\user\AppData\Local\.xmake\packages\o\openssl\1.1.1-w\bea2134730964004af26723afb7a610e\bin\libcrypto-1_1-x64.dll"
生成的删除脚本中该依赖文件的命令
${unRMFileIfExists} "C:\Users\user\AppData\Local\.xmake\packages\o\openssl\1.1.1-w\bea2134730964004af26723afb7a610e\bin\libcrypto-1_1-x64.dll"
结论
软件卸载时没有删除软件目录下的该文件,反而将源文件删除了。

期待的结果

正确的删除安装目录下的文件,而不是源文件

工程配置

set_project("rdpclient")
add_rules("mode.debug", "mode.release")
set_version("0.1.0", {build = "%Y-%m-%d-%H-%M"})

add_configfiles("src/core/config.h.in")
set_configdir("src/core/")
add_requires("fmt", "cereal")
add_requires("openssl", {system = false, configs = {shared = is_kind("shared")}})


includes("@builtin/xpack")
set_languages("c++14")

add_packages("fmt", "cereal", "openssl")
target("rdpclient")
    if is_mode("debug") then
        add_defines("_DEBUG")
    end
    add_rules("qt.widgetapp")
    add_files("src/main/*.cpp")
    add_files("src/main/*.h")
    add_files("src/main/*.ui")

    add_files("src/dialog/*.cpp")
    add_files("src/dialog/*.h")
    add_files("src/dialog/*.ui")

    add_files("src/widgets/*.ui")
    add_files("src/widgets/*.cpp")
    add_files("src/widgets/*.h")

    add_files("src/proto/*.cpp")
    add_files("src/proto/*.hpp")

    -- add_files("src/secure/*.hpp")
    add_files("src/core/*.cpp")
    add_files("src/core/*.hpp")
    -- add sources
    add_files("resources/translation/*.ts")
    add_files("resources/*.qrc")
    add_files("rdpclient.rc")
    -- add_files("resources/translation/*.qm")
    add_frameworks("QtSql", "QtNetwork")

    before_build_files(function (target, sourcebatch, opt)
        for _, sourcebatch in pairs(target:sourcebatches()) do
            local rulename = sourcebatch.rulename
            if rulename == "qt.ts" then
                for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
                    print("Compiling: " .. sourcefile)
                    local tsfilename = path.basename(sourcefile)
                    local tsfilepath = path.directory(sourcefile)
                    local qmfile = path.join(target:targetdir(), tsfilename .. ".qm")
                    os.cp(qmfile, tsfilepath)
                    -- TODO
                end
            end
        end
    end)
target_end()

if is_mode("debug") then
    includes("example")
    includes("tests")
end

xpack("rdpclient")
    set_formats("nsis")
    set_title("RDP Client")
    set_basename("rdpclient-v$(version)-$(plat)-$(arch)")
    add_targets("rdpclient")
    
    on_load(function (package)
        import("core.project.project")
        cprint("${yellow}Export Shared libs")
        import("lib.detect.find_program")
        import("detect.sdks.find_qt")
        local windeployqt = find_program("windeployqt.exe", {paths = find_qt().bindir, check = "--help"})
        local target_dir = package:target("rdpclient"):targetdir()
        local bin_dir = target_dir .. "/bin"
        local rdpclient = target_dir .. "/" .. package:target("rdpclient"):basename() .. ".exe"
        if windeployqt then
            os.vrunv(windeployqt, {"--dir", bin_dir, rdpclient})
        end
        package:add("installfiles", target_dir .. "(/bin/**)")
        package:add("nsis_displayicon", rdpclient)

    end)
    before_installcmd(function (package, batchcmds)
        -- 检查该软件是否正在运行
        batchcmds:rawcmd("nsis", [[
!include "nsProcess.nsh"
nsProcessW::_FindProcess "rdpclient.exe"
nsProcessW::_KillProcess "rdpclient.exe"
nsProcessW::_Unload
        ]])
    end)
    before_uninstallcmd(function (package, batchcmds)
        -- 检查该软件是否正在运行
        batchcmds:rawcmd("nsis", [[
nsProcessW::_FindProcess "rdpclient.exe"
nsProcessW::_KillProcess "rdpclient.exe"
nsProcessW::_Unload
        ]])
    end)

    after_uninstallcmd(function (package, batchcmds)
        -- 删除配置文件
        batchcmds:rawcmd("nsis", [[
SetShellVarContext current
Delete "$LOCALAPPDATA\rdpclient\*"
RMDir /r "$LOCALAPPDATA\rdpclient\*"
RMDir "$LOCALAPPDATA\rdpclient"

Delete "$APPDATA\rdpclient\*"
RMDir /r "$APPDATA\rdpclient\*"
RMDir "$APPDATA\rdpclient"
SetShellVarContext all
        ]])
        -- 删除安装目录下的文件
        batchcmds:rmdir(package:installdir("logs"))
    end)
    set_iconfile("resources/icons/favicon.ico")
    add_components("desktop-icon")

xpack_component("desktop-icon")
    set_default(true)
    set_title("Desktop Icon")
    set_description("create a Desktop Icon")
    on_installcmd(function (component, batchcmds)
        batchcmds:mkdir("$SMPROGRAMS\\rdpclient")
        batchcmds:rawcmd("nsis", [[
                CreateShortCut "$DESKTOP\rdpclient.lnk" "$InstDir\bin\rdpclient.exe"
                CreateShortCut "$InstDir\rdpclient.lnk" "$InstDir\bin\rdpclient.exe"
                CreateShortCut "$SMPROGRAMS\rdpclient\Uninstall.lnk" "$InstDir\uninstall.exe"
                CreateShortCut "$SMPROGRAMS\rdpclient\rdpclient.lnk" "$InstDir\bin\rdpclient.exe"
        ]])
    end)

    after_uninstallcmd(function (package, batchcmds)
        -- 删除快捷方式
        batchcmds:rm("$DESKTOP\\rdpclient.lnk")
        batchcmds:rm("$SMPROGRAMS\\rdpclient\\Uninstall.lnk")
        batchcmds:rm("$SMPROGRAMS\\rdpclient\\rdpclient.lnk")
        batchcmds:rmdir("$SMPROGRAMS\\rdpclient")
        batchcmds:rm("$InstDir\\rdpclient.url")
        batchcmds:rm("$InstDir\\rdpclient.lnk")
    end)

附加信息和错误日志

@liuli-neko liuli-neko added the bug label Dec 10, 2024
@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Title: xpack packaged software deletion script deletes the original file

@waruqi
Copy link
Member

waruqi commented Dec 12, 2024

没看出哪里有问题,最好给个完整可复现的 example,尽可能简化下。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


I don't see any problem. It's best to give a complete and reproducible example and simplify it as much as possible.

@liuli-neko
Copy link
Author

最小步骤如下:

!!!该问题是在windows上使用nsis打包出现的.

1.创建一个项目
xmake create example
2.编辑xmake.lua文件与main.cpp文件使其依赖openssl动态库
xmake.lua

set_project("example")
add_rules("mode.debug", "mode.release")
set_version("1.0.0")
add_requires("openssl", {configs = {shared = true}})
target("example")
    set_kind("binary")
    add_packages("openssl")
    add_files("src/*.cpp")

main.cpp

#include <iostream>
#include <openssl/aes.h>

int main(int argc, char **argv) {
  // AES encryption example
  AES_KEY aes_key;
  AES_set_encrypt_key((const unsigned char *)"0123456789abcdef", 128,
                      &aes_key); // 128-bit key
  unsigned char plaintext[] = "hello world!";
  unsigned char ciphertext[AES_BLOCK_SIZE];
  AES_encrypt(plaintext, ciphertext, &aes_key);
  std::cout << "ciphertext: ";
  for (int i = 0; i < AES_BLOCK_SIZE; i++) {
    std::cout << std::hex << (int)ciphertext[i];
  }
  std::cout << std::endl;
  std::cout << "hello world!" << std::endl;
  return 0;
}

3.增加xpack打包
xmake.lua

includes("@builtin/xpack")
xpack("example")
    set_formats("nsis")
    set_title("example")
    add_targets("example")
    set_description("example")

4.通过xmake打包并安装
xmake pack -v
并安装软件目录如下
C:\PROGRAM FILES\EXAMPLE
│ uninstall.exe

└─bin
example.exe
libcrypto-1_1-x64.dll
5.卸载该软件
安装目录如下
C:\PROGRAM FILES\EXAMPLE
└─bin
libcrypto-1_1-x64.dll
同时xmake安装的openssl依赖文件如下
C:\USERS\USER\APPDATA\LOCAL.XMAKE\PACKAGES\O\OPENSSL\1.1.1-W\CE89F4CA38384BCB91B02B7B4AED2D88\BIN
c_rehash.pl
libcrypto-1_1-x64.pdb
libssl-1_1-x64.dll
libssl-1_1-x64.pdb
openssl.exe
openssl.pdb
6.以上就是操作流程,问题就是错误的删除了原始依赖文件,而不是安装后解压到安装目录下的文件

问题原因排查

在生成的nsis打包脚本中注意到

; add uninstall commands
  ${unRMFileIfExists} "$InstDir\bin\example.exe"
  ${unRMEmptyParentDirs} "$InstDir\bin\example.exe"
  ${unRMFileIfExists} "$InstDir\bin\example.pdb"
  ${unRMEmptyParentDirs} "$InstDir\bin\example.pdb"
  ${unRMFileIfExists} "C:\Users\user\AppData\Local\.xmake\packages\o\openssl\1.1.1-w\ce89f4ca38384bcb91b02b7b4aed2d88\bin\libcrypto-1_1-x64.dll"

卸载命令中删除依赖文件使用的是依赖的绝对路径。

@liuli-neko liuli-neko changed the title xpack打包的软件删除脚本删除原始文件 xpack打包的软件卸载时会删除原始文件 Dec 13, 2024
@liuli-neko liuli-neko changed the title xpack打包的软件卸载时会删除原始文件 xpack打包的软件卸载时会删除依赖的动态库原文件而不是安装目录下的文件 Dec 13, 2024
@waruqi
Copy link
Member

waruqi commented Dec 13, 2024

给完整工程。zip包,我没时间挨个去存文件复原。

@liuli-neko
Copy link
Author

示例工程zip:
example.zip

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Give complete project. zip package, I don’t have time to save the files one by one and restore them.

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Sample project zip:
example.zip

@waruqi
Copy link
Member

waruqi commented Dec 13, 2024

软件卸载时没有删除软件目录下的该文件,反而将源文件删除了。

也没见哪里有删源文件,删包文件 倒是有

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


When the software is uninstalled, the file in the software directory is not deleted, but the source file is deleted.

I haven't seen any deletion of source files or deletion of package files, but there are some.

waruqi added a commit that referenced this issue Dec 13, 2024
@waruqi waruqi mentioned this issue Dec 13, 2024
@waruqi
Copy link
Member

waruqi commented Dec 13, 2024

试下 #5964

@waruqi waruqi added this to the v2.9.7 milestone Dec 13, 2024
waruqi added a commit that referenced this issue Dec 13, 2024
@waruqi waruqi closed this as completed Dec 13, 2024
@liuli-neko
Copy link
Author

liuli-neko commented Dec 13, 2024

软件卸载时没有删除软件目录下的该文件,反而将源文件删除了。

也没见哪里有删源文件,删包文件 倒是有

此前打包的安装包会错误的删除下面这个文件
C:\Users\user\AppData\Local.xmake\packages\o\openssl\1.1.1-w\ce89f4ca38384bcb91b02b7b4aed2d88\bin\libcrypto-1_1-x64.dll
我用最新的dev分支测试正确的删除安装目录下的依赖文件了,多谢。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


When the software is uninstalled, the file in the software directory is not deleted, but the source file is deleted.

I haven’t seen anywhere where source files or package files are deleted, but there are.

The previously packaged installation package will delete the following file by mistake
C:\Users\user\AppData\Local.xmake\packages\o\openssl\1.1.1-w\ce89f4ca38384bcb91b02b7b4aed2d88\bin\libcrypto-1_1-x64.dll
I used the latest dev branch to test and can correctly delete only the dependencies in the installation directory. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants