clash_for_windows_pkg icon indicating copy to clipboard operation
clash_for_windows_pkg copied to clipboard

[Bug]: 安装service mode失败

Open Pil0tXia opened this issue 1 year ago • 9 comments

请认真检查以下清单中的每一项

  • [X] 已经搜索过,没有发现类似issue
  • [x] 已经搜索过文档,没有发现相关内容
  • [x] 已经尝试使用过最新版,问题依旧存在
  • [x] 使用的是官方版本(未替换及修改过安装目录程序文件)

软件版本

0.20.1

操作系统

Windows x64

系统版本

22000.918

问题描述

service mode - install时出现如下画面: image image image

复现步骤

我有两台电脑。PC1从0.19.29直接运行0.20.1安装包升级后,发现service mode图标变红,且点击update和uninstall时提示".../.config/... path not found”,于是我运行0.19.29安装包回退,此时service mode变成灰色,点击uninstall没反应,app也没有重启,于是我再次运行0.20.1安装包,service mode为灰色,但是点击install时出现此报错。用管理员运行也一样有报错。 PC2在升级之前手动uninstall了service mode,升级后为灰色,可以正常install无报错。

日志文件

logs

进入Home Directory/logs文件夹,找到日志文件,将文件拖动至输入框或点击界面左下角小字,将打开文件内容粘贴替换这行

其他补充

No response

Pil0tXia avatar Sep 10 '22 07:09 Pil0tXia

PC1 0.20.1运行卸载;安装0.19.29,并运行卸载;安装0.20.1,install service mode依然同样报错

Pil0tXia avatar Sep 10 '22 07:09 Pil0tXia

删除配置文件夹和clash for windows service后再安装0.20.1同样报错

Pil0tXia avatar Sep 10 '22 07:09 Pil0tXia

20.2 无论是install uninstall update全是fail。 uninstall、update后service inactive install后service active,图标变红

Quetweilan avatar Sep 10 '22 08:09 Quetweilan

删除配置文件夹和clash for windows service后再安装0.20.1同样报错

删干净文件夹之后安装0.20.2,可以正常安装service mode了

Pil0tXia avatar Sep 10 '22 08:09 Pil0tXia

删除配置文件夹和clash for windows service后再安装0.20.1同样报错

删干净文件夹之后安装0.20.2,可以正常安装service mode了

谢谢

2021521 avatar Sep 10 '22 09:09 2021521

删除配置文件夹和clash for windows service后再安装0.20.1同样报错

删干净文件夹之后安装0.20.2,可以正常安装service mode了

我全删干净重新安装 0.20.2 之后 service mode 自动变成绿色的,但 .config/clash 里面并没有 service 文件夹,按 install 和 uninstall 还是会显示失败, tun mode 也不能使用,请问你遇到这个问题了吗?

lincolnlyj avatar Sep 10 '22 13:09 lincolnlyj

删除配置文件夹和clash for windows service后再安装0.20.1同样报错

删干净文件夹之后安装0.20.2,可以正常安装service mode了

我全删干净重新安装 0.20.2 之后 service mode 自动变成绿色的,但 .config/clash 里面并没有 service 文件夹,按 install 和 uninstall 还是会显示失败, tun mode 也不能使用,请问你遇到这个问题了吗?

新版本的服务在program files里面

Pil0tXia avatar Sep 10 '22 14:09 Pil0tXia

删除配置文件夹和clash for windows service后再安装0.20.1同样报错

删干净文件夹之后安装0.20.2,可以正常安装service mode了

我全删干净重新安装 0.20.2 之后 service mode 自动变成绿色的,但 .config/clash 里面并没有 service 文件夹,按 install 和 uninstall 还是会显示失败, tun mode 也不能使用,请问你遇到这个问题了吗?

新版本的服务在program files里面

哦哦,找到了,可以安装和卸载 service mode 了,可是我的 tun mode 还是一直用不了不知道为什么

lincolnlyj avatar Sep 10 '22 14:09 lincolnlyj

WinSW 这么邪?😨

@Fndroid 试试 PowerShell?

remove-cfw-service.js

// @ts-check

"use strict";

const cp = require("node:child_process");
const path = require("node:path");

/**
 * @param {string} command - The PowerShell command to run.
 * @returns The Base64-encoded string of the command, which PowerShell's `EncodedCommand` parameter can accept.
 * @see {@link https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding.unicode}
 */
const getPwshEncodedCommand = (command) => Buffer.from(command, "utf16le").toString("base64");

/**
 * Runs some PowerShell commands with Administrator privilege.
 * This should trigger UAC when the caller is not elevated.
 *
 * @param {string} command - The PowerShell command to run.
 * @returns A Promise.
 *
 * It resolves when the command seems to finish.
 *
 * It rejects when any of the following occurs:
 * * The command causes PowerShell to exit with a non-zero code.
 * * The command cannot be started.
 * * The underlying process cannot be spawned.
 * @see {@link https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe}
 * @see {@link https://nodejs.org/api/child_process.html}
 */
const runAsAdministrator = (command) => {
    const encodedCommand = getPwshEncodedCommand(command);

    // This will be passed to PowerShell as the `-c` (`Command`) argument.
    // https://nodejs.org/api/child_process.html#shell-requirements
    // Then, the `Start-Process` cmdlet starts another PowerShell with Administrator privilege.
    // Be careful about Windows command-line quoting rules when constructing `ArgumentList`.
    const runnerCommand =
        String.raw`$ErrorActionPreference = 'Stop'; $Executor = Start-Process -FilePath "$PSHOME\powershell.exe" -Verb RunAs -Wait -ArgumentList '-NoProfile -ExecutionPolicy RemoteSigned -EncodedCommand "` +
        encodedCommand +
        String.raw`"' -PassThru; exit $Executor.ExitCode`;

    return new Promise((resolve, reject) => {
        const runner = cp.spawn(runnerCommand, void 0, {
            cwd: process.env.TEMP,
            // Use the well-known path of Windows PowerShell. This is the simplest solution.
            shell: path.resolve(process.env.SystemRoot, String.raw`System32\WindowsPowerShell\v1.0\powershell.exe`),
            stdio: "ignore",
        });

        runner.on("error", (e) => {
            reject(e);
        });

        runner.on("close", (code) => {
            code ? reject(code) : resolve(code);
        });
    });
};

const pwshCommand = String.raw`
$ErrorActionPreference = 'Stop'

$CfwService = Get-CimInstance -ClassName Win32_Service -Filter 'Name = "Clash Core Service"' -ErrorAction Continue
if ($CfwService)
{
    Invoke-CimMethod -InputObject $CfwService -MethodName StopService
    Invoke-CimMethod -InputObject $CfwService -MethodName Delete
    Remove-Item -Recurse -Force -LiteralPath $(Split-Path -Parent -Path $CfwService.PathName.Trim('"')) -ErrorAction Continue
}

$OrphanedPath = "$env:USERPROFILE\.config\clash\service"
icacls.exe $OrphanedPath /reset /T /C
Remove-Item -Recurse -Force -LiteralPath $OrphanedPath -ErrorAction Continue
Remove-Item -Recurse -Force -LiteralPath "$env:ProgramFiles\Clash for Windows Service" -ErrorAction Continue
exit 0
`;

runAsAdministrator(pwshCommand);

remove-cfw-service_ps-7.ps1

如果有 PowerShell 7,还可用另外一套命令来停止 service。

#Requires -Version 7
#Requires -RunAsAdministrator

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

# Remove the currently registered service.
$CfwService = Get-Service -Name 'Clash Core Service' -ErrorAction Continue
if ($CfwService)
{
    Stop-Service -InputObject $CfwService -NoWait
    Remove-Service -InputObject $CfwService -Confirm

    # The `PathName` (`BinaryPathName`) is essentially command line as per the `QUERY_SERVICE_CONFIG` structure.
    # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-scmr/97200665-5631-42ea-9917-6f9b41f02391
    # For CFW, it's a quoted fully qualified Windows file system path, because there is no argument.
    # So we can safely trim the string.
    Remove-Item -Recurse -Force -LiteralPath $(Split-Path -Parent -Path $CfwService.BinaryPathName.Trim('"')) -ErrorAction Continue -Confirm
}

# Remove the orphaned service directory in the Home Directory.
$OrphanedPath = "$env:USERPROFILE\.config\clash\service"
icacls.exe $OrphanedPath /reset /T /C
Remove-Item -Recurse -Force -LiteralPath $OrphanedPath -ErrorAction Continue -Confirm

# Remove the potentially corrupted service directory in the Program Files.
Remove-Item -Recurse -Force -LiteralPath "$env:ProgramFiles\Clash for Windows Service" -ErrorAction Continue -Confirm

exit 0

Lemmingh avatar Sep 11 '22 03:09 Lemmingh