Enhance Windows support by updating artifact configuration and improving extraction logic

This commit is contained in:
crazywhalecc
2025-12-11 11:35:12 +08:00
parent dc05ad23c9
commit 2080407283
21 changed files with 382 additions and 181 deletions

View File

@@ -120,7 +120,7 @@ class FileSystem
$src_path = FileSystem::convertPath($from);
switch (PHP_OS_FAMILY) {
case 'Windows':
f_passthru('xcopy "' . $src_path . '" "' . $dst_path . '" /s/e/v/y/i');
cmd(false)->exec('xcopy "' . $src_path . '" "' . $dst_path . '" /s/e/v/y/i');
break;
case 'Linux':
case 'Darwin':
@@ -137,7 +137,7 @@ class FileSystem
* @param string $from Source file path
* @param string $to Destination file path
*/
public static function copy(string $from, string $to): void
public static function copy(string $from, string $to): bool
{
logger()->debug("Copying file from {$from} to {$to}");
$dst_path = FileSystem::convertPath($to);
@@ -145,6 +145,7 @@ class FileSystem
if (!copy($src_path, $dst_path)) {
throw new FileSystemException('Cannot copy file from ' . $src_path . ' to ' . $dst_path);
}
return true;
}
/**
@@ -317,7 +318,12 @@ class FileSystem
}
} elseif (is_link($sub_file) || is_file($sub_file)) {
if (!unlink($sub_file)) {
return false;
$cmd = PHP_OS_FAMILY === 'Windows' ? 'del /f /q' : 'rm -f';
f_exec("{$cmd} " . escapeshellarg($sub_file), $out, $ret);
if ($ret !== 0) {
logger()->warning('Remove file failed: ' . $sub_file);
return false;
}
}
}
}

View File

@@ -107,6 +107,8 @@ class GlobalEnvManager
{
if (SystemTarget::isUnix() && !str_contains(getenv('PATH'), $path)) {
self::putenv("PATH={$path}:" . getenv('PATH'));
} elseif (SystemTarget::getTargetOS() === 'Windows' && !str_contains(getenv('PATH'), $path)) {
self::putenv("PATH={$path};" . getenv('PATH'));
}
}

View File

@@ -15,13 +15,10 @@ class WindowsUtil
* @param array $paths search path (default use env path)
* @return null|string null if not found, string is absolute path
*/
public static function findCommand(string $name, array $paths = [], bool $include_sdk_bin = false): ?string
public static function findCommand(string $name, array $paths = []): ?string
{
if (!$paths) {
$paths = explode(PATH_SEPARATOR, getenv('Path'));
if ($include_sdk_bin) {
$paths[] = getenv('PHP_SDK_PATH') . '\bin';
}
}
foreach ($paths as $path) {
if (file_exists($path . DIRECTORY_SEPARATOR . $name)) {
@@ -34,29 +31,35 @@ class WindowsUtil
/**
* Find Visual Studio installation.
*
* @return array<string, string>|false False if not installed, array contains 'version' and 'dir'
* @return array{
* version: string,
* major_version: string,
* dir: string
* }|false False if not installed, array contains 'version' and 'dir'
*/
public static function findVisualStudio(): array|false
{
$check_path = [
'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe' => 'vs17',
'C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe' => 'vs17',
'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\MSBuild.exe' => 'vs17',
'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe' => 'vs16',
'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe' => 'vs16',
'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' => 'vs16',
// call vswhere (need VS and C++ tools installed), output is json
$vswhere_exec = PKG_ROOT_PATH . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'vswhere.exe';
$args = [
'-latest',
'-format', 'json',
'-requires', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
];
foreach ($check_path as $path => $vs_version) {
if (file_exists($path)) {
$vs_ver = $vs_version;
$d_dir = dirname($path, 4);
return [
'version' => $vs_ver,
'dir' => $d_dir,
];
}
$cmd = escapeshellarg($vswhere_exec) . ' ' . implode(' ', $args);
$result = f_exec($cmd, $out, $code);
if ($code !== 0 || !$result) {
return false;
}
return false;
$json = json_decode(implode("\n", $out), true);
if (!is_array($json) || count($json) === 0) {
return false;
}
return [
'version' => $json[0]['installationVersion'],
'major_version' => explode('.', $json[0]['installationVersion'])[0],
'dir' => $json[0]['installationPath'],
];
}
/**