创建 abp.io Abp VNext 项目
通过源代码模板创建项目
下载官网源代码 https://github.com/abpframework/abp
代码
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
public class AbpIoAppTemplateCreate
{
public string VoloAbpVersion { get; set; } = "8.3.4";
public string SourceCompanyName { get; set; } = "MyCompanyName";
public string SourceProjectName { get; set; } = "MyProjectName";
public string TargetCompanyName { get; set; }
public string TargetProjectName { get; set; }
public void Run(string sourceDir, string destDir)
{
PackageVersions = new Dictionary<string, string>();
CopyDirectoryWithRename(sourceDir, destDir);
XElement xml = new XElement("Project",
//from user in users
//select new XElement("User",
// new XAttribute("id", user.ID),
// new XElement("Name", user.Name),
// new XElement("Email", user.Email)
//)
new XElement("PropertyGroup", new XElement("ManagePackageVersionsCentrally", "true")),
new XElement("ItemGroup", from item in PackageVersions.OrderBy(x => x.Key) select new XElement("PackageVersion", new XAttribute("Include", item.Key), new XAttribute("Version", item.Value))
));
xml.Save(@$"{destDir}\Directory.Packages.props");
}
/// <summary>
/// 复制文件夹并重命名以特定字符串开头的文件夹和文件。
/// </summary>
/// <param name="sourceDir">源文件夹路径(例如:@"C:\Source")。</param>
/// <param name="destDir">目标文件夹路径(例如:@"D:\Destination")。</param>
private void CopyDirectoryWithRename(string sourceDir, string destDir)
{
// 检查源目录是否存在
if (!Directory.Exists(sourceDir))
{
throw new DirectoryNotFoundException($"源目录不存在: {sourceDir}");
}
//if (Directory.Exists(destDir))
//{
// throw new DirectoryNotFoundException($"目标目录已存在: {destDir}");
//}
// 创建目标根目录(如果不存在)
Directory.CreateDirectory(destDir);
// 复制当前目录中的所有文件
foreach (string sourceFilePath in Directory.GetFiles(sourceDir))
{
// 获取文件名并应用重命名逻辑
string fileName = Path.GetFileName(sourceFilePath);
string newFileName = ApplyNameReplacement(fileName); // 应用名称替换
string destFilePath = Path.Combine(destDir, newFileName);
// 复制文件,允许覆盖已存在的文件
File.Copy(sourceFilePath, destFilePath, true);
ReplaceFileContent(destFilePath); // 处理文件内容
}
// 递归复制所有子目录
foreach (string sourceSubDir in Directory.GetDirectories(sourceDir))
{
// 获取子目录名并应用重命名逻辑
string subDirName = Path.GetFileName(sourceSubDir);
string newSubDirName = ApplyNameReplacement(subDirName); // 应用名称替换
string destSubDirPath = Path.Combine(destDir, newSubDirName);
// 递归调用以处理子目录
CopyDirectoryWithRename(sourceSubDir, destSubDirPath);
}
}
Dictionary<string, string> PackageVersions;
/// <summary>
/// 应用名称替换逻辑:如果名称以"MyCompanyName"开头,则替换为"TargetCompanyName.TargetProjectName"。
/// </summary>
/// <param name="originalName">原始名称。</param>
/// <returns>替换后的名称。</returns>
private string ApplyNameReplacement(string originalName)
{
string oldPrefix = $"{SourceCompanyName}.{SourceProjectName}";
string newPrefix = $"{TargetCompanyName}.{TargetProjectName}";
string oldPrefix2 = $"{SourceProjectName}";
string newPrefix2 = $"{TargetProjectName}";
// 检查名称是否以指定前缀开头
if (originalName.StartsWith(oldPrefix, StringComparison.OrdinalIgnoreCase)) // 忽略大小写
{
// 替换前缀:移除旧前缀,添加新前缀
return newPrefix + originalName.Substring(oldPrefix.Length);
}
if (originalName.StartsWith(oldPrefix2, StringComparison.OrdinalIgnoreCase)) // 忽略大小写
{
// 替换前缀:移除旧前缀,添加新前缀
return newPrefix2 + originalName.Substring(oldPrefix2.Length);
}
return originalName; // 如果不匹配,返回原名称
}
void ReplaceFileContent(string filePath)
{
// 跳过二进制文件 [4]()
string ext = Path.GetExtension(filePath).ToLower();
if (ext == ".dll" || ext == ".exe" || ext == ".png" || ext == ".jpg")
return;
try
{
// 读取并替换内容
string content = File.ReadAllText(filePath, Encoding.UTF8);
content = content.Replace("MyCompanyName", TargetCompanyName);
content = content.Replace("MyProjectName", TargetProjectName);
if (ext == ".csproj")
{
var set = ExtractToHashSet(
content,
@"(Volo\.Abp[^\\]*?)\.csproj",
RegexOptions.IgnoreCase);
foreach (var item in set)
{
PackageVersions.TryAdd(item.Replace(".csproj", string.Empty), VoloAbpVersion);
}
}
if (ext == ".csproj")
{
var set = ExtractToHashSet(
content,
@"<PackageReference\s+Include=""(.*?)""\s+Version=""(.*?)""",
RegexOptions.IgnoreCase);
foreach (var item in set)
{
var otherPackage = Regex.Replace(item, @"<PackageReference\s+Include=""(.*?)""\s+Version=""(.*?)""", "$1|$2").Split('|');
PackageVersions.TryAdd(otherPackage[0], otherPackage[1]);
}
}
content = Regex.Replace(content, @"<PackageReference\s+Include=""(.*?)""\s+Version=""(.*?)""", "<PackageReference Include=\"$1\"");
content = Regex.Replace(content, @"<ProjectReference.*?(Volo\.Abp[^\\]*?)\.csproj", $"<PackageReference Include=\"$1");
File.WriteAllText(filePath, content, Encoding.UTF8);
}
catch (Exception ex)
{
Console.WriteLine($"处理文件 {filePath} 时出错: {ex.Message}");
}
}
public static HashSet<string> ExtractToHashSet(
string input,
string pattern,
RegexOptions options = RegexOptions.None)
{
if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(pattern))
return new HashSet<string>(StringComparer.OrdinalIgnoreCase); // 或根据需要选 Ordinal/OrdinalIgnoreCase
var matches = Regex.Matches(input, pattern, options);
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase); // 默认忽略大小写去重;如需区分大小写,改用 StringComparer.Ordinal
foreach (Match match in matches)
{
if (match.Success && match.Groups.Count > 0)
{
// 优先取整个匹配(Group[0]),也可指定 Group 名或索引(如 match.Groups["name"].Value)
string value = match.Value.Trim();
if (!string.IsNullOrEmpty(value))
set.Add(value);
}
}
return set;
}
}
运行
new AbpIoAppTemplateCreate() { TargetCompanyName= "创建公司名", TargetProjectName= "创建的项目名" }.Run(@"D:\abp源代码目录\templates\app\aspnet-core", @"D:\Demo\NetCore");

浙公网安备 33010602011771号