diff --git a/Windows/CS/Framework4.0/Utils/Utils/Util.cs b/Windows/CS/Framework4.0/Utils/Utils/Utils.cs
similarity index 63%
rename from Windows/CS/Framework4.0/Utils/Utils/Util.cs
rename to Windows/CS/Framework4.0/Utils/Utils/Utils.cs
index aadc160..0461e99 100644
--- a/Windows/CS/Framework4.0/Utils/Utils/Util.cs
+++ b/Windows/CS/Framework4.0/Utils/Utils/Utils.cs
@@ -1,5 +1,6 @@
-using System;
+using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text;
@@ -8,9 +9,15 @@ namespace JoyD.Windows.CS
///
/// 通用工具和方法
///
- public static class Util
+ public static class Utils
{
- // CRC16/XMODEM算法实现(带起始位置和长度)
+ ///
+ /// 使用CRC16/XMODEM算法计算字节数组的CRC16校验值
+ ///
+ /// 要计算CRC16的数据字节数组
+ /// 计算的起始位置索引
+ /// 要计算的字节长度
+ /// 计算得到的CRC16校验值
public static ushort CalculateCRC16(byte[] data, int startIndex, int length)
{
ushort crc = 0;
@@ -31,13 +38,22 @@ namespace JoyD.Windows.CS
- // CRC32-MPEG2算法实现
+ ///
+ /// 使用CRC32-MPEG2算法计算字节数组的CRC32校验值
+ ///
+ /// 要计算CRC32的数据字节数组
+ /// 计算得到的CRC32校验值
public static uint CalculateCRC32(byte[] data)
{
return CalculateCRC32(0xFFFFFFFF, data);
}
- // 支持增量计算的CRC32方法
+ ///
+ /// 支持增量计算的CRC32-MPEG2算法实现
+ ///
+ /// 初始CRC值(用于增量计算)
+ /// 要计算CRC32的数据字节数组
+ /// 计算得到的CRC32校验值
public static uint CalculateCRC32(uint crc, byte[] data)
{
uint polynomial = 0x04C11DB7;
@@ -56,7 +72,14 @@ namespace JoyD.Windows.CS
return crc;
}
- // 计算文件的CRC32(通过文件路径)
+ ///
+ /// 通过文件路径计算文件的CRC32校验值
+ ///
+ /// 文件的完整路径
+ /// 计算得到的CRC32校验值
+ /// 当文件路径为空或无效时抛出
+ /// 当指定路径的文件不存在时抛出
+ /// 当文件读取失败时抛出
public static uint CalculateFileCRC32(string filePath)
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
@@ -65,7 +88,13 @@ namespace JoyD.Windows.CS
}
}
- // 计算文件的CRC32(通过已打开的文件流)
+ ///
+ /// 通过已打开的文件流计算文件的CRC32校验值
+ ///
+ /// 已打开的文件流
+ /// 计算得到的CRC32校验值
+ /// 当文件流为null时抛出
+ /// 当文件读取失败时抛出
public static uint CalculateCRC32(FileStream fs)
{
uint crc = 0xFFFFFFFF;
@@ -105,19 +134,44 @@ namespace JoyD.Windows.CS
return crc;
}
- // byte[]转base64编码
+ ///
+ /// 将字节数组转换为Base64编码的字符串
+ ///
+ /// 要转换的字节数组
+ /// Base64编码的字符串
+ /// 当输入数据为null时抛出
public static string ByteArrayToBase64(byte[] data)
{
return Convert.ToBase64String(data);
}
- // base64转byte[]编码
+ ///
+ /// 将Base64编码的字符串转换为字节数组
+ ///
+ /// Base64编码的字符串
+ /// 转换后的字节数组
+ /// 当输入字符串为null时抛出
+ /// 当输入字符串不是有效的Base64格式时抛出
public static byte[] Base64ToByteArray(string base64)
{
return Convert.FromBase64String(base64);
}
- // 构建不含前缀的FTPC命令(返回byte[],直接处理字节流)
+ ///
+ /// 构建不含前缀的FTPC命令字节流
+ ///
+ /// 命令字符(ASCII编码)
+ /// 命令参数,支持以下类型:
+ ///
+ /// - long: 24位大端序数据(如filesize24或addr24)
+ /// - ushort: 16位大端序数据长度
+ /// - uint: 32位大端序数据(如CRC32值)
+ /// - string: ASCII编码的字符串参数
+ /// - byte[]: 原始字节数组参数
+ ///
+ ///
+ /// 包含命令、参数和CRC16校验的完整字节数组
+ /// 当参数类型不支持时抛出
public static byte[] BuildRawFTPCommand(char command, params object[] parameters)
{
using (MemoryStream ms = new MemoryStream())
@@ -205,7 +259,12 @@ namespace JoyD.Windows.CS
}
}
- // 构建完整通信命令(接受byte[]输入)
+ ///
+ /// 构建完整的通信命令字符串
+ ///
+ /// 通过BuildRawFTPCommand方法构建的原始FTPC命令字节流
+ /// 完整的通信命令字符串,格式为:set(LFMGR: FTPC, "base64_encoded_command")
+ /// 当输入命令字节流为null时抛出
public static string BuildCommunicationCommand(byte[] rawFTPCommand)
{
string base64 = Convert.ToBase64String(rawFTPCommand);
diff --git a/Windows/CS/Framework4.0/Utils/Utils/Utils.csproj b/Windows/CS/Framework4.0/Utils/Utils/Utils.csproj
index 2fcb5cf..bbe9a8b 100644
--- a/Windows/CS/Framework4.0/Utils/Utils/Utils.csproj
+++ b/Windows/CS/Framework4.0/Utils/Utils/Utils.csproj
@@ -8,10 +8,11 @@
Library
Properties
JoyD.Windows.CS
- Utils
+ JoyD.Windows.CS.Utils
v4.0
512
true
+ Client
true
@@ -21,7 +22,7 @@
DEBUG;TRACE
prompt
4
- bin\Debug\Utils.xml
+ bin\Debug\JoyD.Windows.CS.Utils.xml
pdbonly
@@ -45,7 +46,7 @@
-
+
diff --git a/Windows/CS/Framework4.0/Utils/publish-nuget.ps1 b/Windows/CS/Framework4.0/Utils/publish-nuget.ps1
new file mode 100644
index 0000000..24faa8b
--- /dev/null
+++ b/Windows/CS/Framework4.0/Utils/publish-nuget.ps1
@@ -0,0 +1,319 @@
+# 托普瑞控制库发布脚本 请在 chcp 65001下运行
+
+# 配置参数 - 基本设置
+$scriptDir = Get-Location
+$output = Join-Path $scriptDir "Output"
+$server = "http://47.111.181.23:8081/repository/nuget-releases/"
+$key = "admin:admin"
+$actualDllName = "JoyD.Windows.CS.Utils.dll"
+$targetDllName = "JoyD.Windows.CS.Utils.dll" # 保持与AssemblyName一致,避免引用问题
+
+# NuGet包元数据配置 - 在此处修改所有元数据
+$packageId = "com.joyd.utils"
+$version = "1.0.0.0" # 更新版本号以确保用户安装的是修复后的版本
+$title = "通用工具库"
+$authors = "曾庆明"
+$owners = "JoyD Technology"
+$description = "通用工具库,提供一些常用的工具函数和扩展方法"
+$copyright = "Copyright 2025 JoyD Technology"
+$tags = @("utils", "工具库")
+$projectUrl = "https://github.com/joyd/utils"
+$licenseUrl = "https://opensource.org/licenses/MIT"
+$iconFileName = "Utils.ico"
+$iconSourcePath = Join-Path $scriptDir $iconFileName
+$iconUrl = "http://47.111.181.23:8081/repository/gradle/main/Utils.ico"
+$releaseNotes = "初始版本发布"
+
+# 其他设置
+$nupkgFileName = "$packageId.$version.nupkg"
+$nupkgFilePath = Join-Path $output $nupkgFileName
+
+Write-Host "========== 工具库发布开始 =========="
+
+# 创建输出目录
+if (!(Test-Path $output)) {
+ New-Item -ItemType Directory -Path $output -Force | Out-Null
+ Write-Host "已创建输出目录: $output"
+} else {
+ Write-Host "使用现有输出目录: $output"
+}
+
+# 清理之前的构建文件
+Write-Host "清理之前的构建文件.."
+if (Test-Path "$output\$actualDllName") { Remove-Item -Path "$output\$actualDllName" -Force }
+if (Test-Path "$output\$targetDllName") { Remove-Item -Path "$output\$targetDllName" -Force }
+if (Test-Path "$output\$nupkgFileName") { Remove-Item -Path "$output\$nupkgFileName" -Force }
+if (Test-Path "$output\$packageId.nuspec") { Remove-Item -Path "$output\$packageId.nuspec" -Force }
+
+# 构建项目
+Write-Host "1. 正在构建项目..."
+Write-Host "当前目录: $scriptDir"
+dotnet build "$scriptDir\Utils\Utils.csproj" -c Release -o "$output"
+
+if ($LASTEXITCODE -ne 0) {
+ Write-Host "错误: 构建失败!" -ForegroundColor Red
+ exit 1
+}
+
+# 验证DLL是否存在
+if (!(Test-Path "$output\$actualDllName")) {
+ Write-Host "错误: 在输出目录中找不到$actualDllName!" -ForegroundColor Red
+ exit 1
+}
+
+# 直接使用实际DLL文件,不进行重命名
+Write-Host "使用实际DLL文件: $actualDllName 用于打包"
+
+# 复制图标文件到输出目录
+if (Test-Path $iconSourcePath) {
+ Copy-Item -Path $iconSourcePath -Destination (Join-Path $output $iconFileName) -Force
+ Write-Host "已复制图标文件到输出目录: $iconFileName"
+} else {
+ Write-Host "警告: 图标文件 $iconSourcePath 不存在,将使用默认图标" -ForegroundColor Yellow
+}
+
+Write-Host "2. 准备打包文件..."
+
+# 在Output目录创建NuGet.Config文件,这样dotnet nuget push命令就能正确找到它
+$localNugetConfigPath = Join-Path -Path $output -ChildPath "NuGet.Config"
+
+# 创建包含全面配置的NuGet.Config文件
+$nugetConfigContent = @"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+"@
+
+# 设置配置文件
+Set-Content -Path $localNugetConfigPath -Value $nugetConfigContent
+Write-Host "已在Output目录设置NuGet.Config: $localNugetConfigPath"
+
+# 创建一个简单的.csproj文件用于打包,无需还原
+$tempProjContent = @"
+
+
+ net40
+ $packageId
+ $version
+ $title
+ $authors
+ $owners
+ $description
+ $copyright
+ $tagsString
+ $projectUrl
+ $licenseUrl
+ $iconFileName
+
+ $releaseNotes
+ .
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+"@
+
+$tempProjPath = "$output\Temp.csproj"
+Set-Content -Path $tempProjPath -Value $tempProjContent
+
+# 在输出目录中创建包结构
+Write-Host "3. 创建NuGet包.."
+
+# 在输出目录中创建完整的nuspec文件
+$nuspecPath = Join-Path $output "$packageId.nuspec"
+
+# 将tags数组转换为空格分隔的字符串
+$tagsString = $tags -join " "
+
+$nuspecContent = @"
+
+
+
+ $packageId
+ $version
+ $title
+ $authors
+ $owners
+ false
+ $description
+ $releaseNotes
+ $copyright
+ $tagsString
+ $projectUrl
+ $licenseUrl
+ $iconFileName
+ $iconUrl
+
+
+
+
+
+
+
+
+
+
+
+
+"@
+
+Set-Content -Path $nuspecPath -Value $nuspecContent -Encoding UTF8
+Write-Host "已创建nuspec文件: $nuspecPath"
+
+# 手动创建nupkg包结构
+Write-Host "创建包结构.."
+$tempDir = Join-Path $output "temp_pkg"
+
+# 确保临时目录存在
+if (!(Test-Path $tempDir)) {
+ New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
+}
+
+# 创建lib/net40子目录
+$libDir = Join-Path $tempDir "lib\net40"
+if (!(Test-Path $libDir)) {
+ New-Item -ItemType Directory -Path $libDir -Force | Out-Null
+}
+
+# 复制DLL到包结构中
+$sourceDllPath = Join-Path $output $targetDllName
+$destDllPath = Join-Path $libDir $targetDllName
+Copy-Item -Path $sourceDllPath -Destination $destDllPath -Force
+Write-Host "已复制$sourceDllPath 到$destDllPath"
+
+# 复制图标文件到包结构根目录
+$sourceIconPath = Join-Path $output $iconFileName
+$destIconPath = Join-Path $tempDir $iconFileName
+if (Test-Path $sourceIconPath) {
+ Copy-Item -Path $sourceIconPath -Destination $destIconPath -Force
+ Write-Host "已复制图标文件到包结构: $destIconPath"
+} else {
+ Write-Host "警告: 在输出目录中找不到图标文件 $sourceIconPath" -ForegroundColor Yellow
+}
+
+# 创建[Content_Types].xml文件(有效nupkg必需)
+$contentTypesPath = Join-Path $tempDir "[Content_Types].xml"
+# 使用-LiteralPath参数避免方括号被解释为通配符
+Set-Content -LiteralPath $contentTypesPath -Value ""
+Write-Host "已在 $contentTypesPath 创建[Content_Types].xml"
+
+# 复制nuspec文件到包结构根目录
+$sourceNuspecPath = Join-Path $output "$packageId.nuspec"
+$destNuspecPath = Join-Path $tempDir "$packageId.nuspec"
+if (Test-Path $sourceNuspecPath) {
+ Copy-Item -Path $sourceNuspecPath -Destination $destNuspecPath -Force
+ Write-Host "已复制nuspec文件到包结构: $destNuspecPath"
+} else {
+ Write-Host "警告: 找不到nuspec文件 $sourceNuspecPath" -ForegroundColor Yellow
+}
+
+# 创建zip文件并将其重命名为nupkg
+$zipPath = Join-Path $output "temp_manual.zip"
+
+# 清理任何现有文件
+if (Test-Path $zipPath) {
+ Remove-Item -Path $zipPath -Force
+ Write-Host "已移除现有的zip文件"
+}
+if (Test-Path $nupkgFilePath) {
+ Remove-Item -Path $nupkgFilePath -Force
+ Write-Host "已移除现有的nupkg文件"
+}
+
+Write-Host "从$tempDir\* 创建zip归档到$zipPath..."
+Compress-Archive -Path "$tempDir\*" -DestinationPath $zipPath -Force
+
+if (Test-Path $zipPath) {
+ Write-Host "正在将$zipPath 重命名为 $nupkgFilePath..."
+ Rename-Item -Path $zipPath -NewName $nupkgFileName -Force
+
+ if (Test-Path $nupkgFilePath) {
+ $nupkgFile = Get-Item $nupkgFilePath
+ Write-Host "✅ 成功创建包: $($nupkgFile.FullName)"
+ Write-Host "包大小: $([math]::Round($nupkgFile.Length / 1KB, 2)) KB"
+ }
+}
+
+# 清理临时文件夹
+Remove-Item -Path $tempDir -Recurse -Force
+Write-Host "已清理临时文件夹"
+
+# 检查包文件是否存在
+if (Test-Path $nupkgFilePath) {
+ $nupkgFile = Get-Item $nupkgFilePath
+ Write-Host "找到包文件: $($nupkgFile.FullName)"
+ Write-Host "4. 正在发布包到仓库..."
+
+ # 使用curl直接发布到HTTP仓库
+ Write-Host "使用curl直接发布到HTTP仓库..."
+
+ # 构建curl命令
+ $curlCommand = "curl.exe -X PUT -u $key -F package=@$nupkgFilePath $server"
+ Write-Host "正在执行: $curlCommand"
+
+ # 执行curl命令(使用curl.exe避免PowerShell别名冲突)
+ & curl.exe -X PUT -u $key -F package=@$nupkgFilePath $server
+
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host "✅ 成功: 包发布成功" -ForegroundColor Green
+ Write-Host "包ID: $packageId"
+ Write-Host "版本: $version"
+ Write-Host "标题: $title"
+ Write-Host "作者: $authors"
+ Write-Host "所有者: $owners"
+ Write-Host "描述: $description"
+ Write-Host "标签: $tagsString"
+ Write-Host "仓库: $server"
+ } else {
+ Write-Host "❌ 错误: 包创建成功但发布失败" -ForegroundColor Red
+ Write-Host "包文件位置: $($nupkgFile.FullName)"
+ Write-Host "
+您可以尝试手动发布(使用curl命令):"
+ Write-Host "curl -X PUT -u admin:admin -F \"package=@$($nupkgFile.FullName)\" $server"
+ Write-Host "
+或者直接在项目中使用创建的包文件"
+ }
+} else {
+ Write-Host "❌ 错误: 未创建NuGet包" -ForegroundColor Red
+ Write-Host "请检查dotnet CLI是否正确配置"
+ Write-Host "您可以尝试使用Output目录中的文件手动创建包"
+}
+
+# 最终清理
+Write-Host "正在执行最终清理.."
+if (Test-Path "$output\Temp.csproj") {
+ Remove-Item -Path "$output\Temp.csproj" -Force
+ Write-Host "已移除Temp.csproj"
+}
+
+# 删除我们在Output目录创建的NuGet.Config文件
+if (Test-Path $localNugetConfigPath) {
+ Remove-Item -Path $localNugetConfigPath -Force
+ Write-Host "已删除临时创建的NuGet.Config"
+}
+
+Write-Host "发布过程完成"
\ No newline at end of file