使用 nuspec 的 Nuget 包 csproj
Nuget pack csproj using nuspec
我想创建一个仅包含我的 nuspec 文件中指定的内容的 nuget 包,但仍然从我的 csproj 中获取版本。为了使用令牌,我必须像这样打包:
nuget pack MyProj.csproj
但是当我这样做时,它会添加一些依赖项并在我的 nuget 包中创建一个不需要的文件夹。我的 nuspec 文件是:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Test</id>
<version>$version$</version>
<title>Test</title>
<authors>Test</authors>
<owners>Test</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Test</description>
<summary>Test</summary>
<releaseNotes>Test</releaseNotes>
<copyright>Test</copyright>
</metadata>
<files>
<file src="bin\Debug\*.dll" target="lib\net45" />
<file src="bin\Debug\MyProj.Wpf.exe" target="lib\net45" />
<file src="bin\Debug\MyProj.Wpf.exe.config" target="lib\net45" />
</files>
</package>
当我 运行 打包命令时,它添加的额外文件是目标中的 MyProj.Wpf.exe="lib\net452"
我可以强制它不添加依赖项和这个额外的文件吗?或者只执行 nuspec 中指定的操作?
我 post 回答这个问题已经有一段时间了。从那以后,我使用了一个对我有用的解决方案,所以我将在这里 post 为任何需要它的人提供。
我创建了一个 .csproj,它修改了 .nuspec 文件并根据 .csproj 的程序集文件设置了它的版本。为了减少手动工作,我创建了一个 .bat 文件,它使用参数调用这个 .exe,并完成了安装程序的创建。我使用 Squirrel.Windows 创建安装程序。
我创建了一个 NuspectVersionSetter.csproj 来设置 nuspec 版本。有很多方法可以实现这个,这里有一个简单的方法:
static void Main(string[] args)
{
try
{
if (args.Length < 2)
{
throw new Exception("Args are not correct");
}
var assemblyFilePath = args[0];
var nuspecFilePath = args[1];
IsFileValid(assemblyFilePath, ".cs");
IsFileValid(nuspecFilePath, ".nuspec");
var version = GetAssemblyVersion(assemblyFilePath);
if (string.IsNullOrEmpty(version))
{
throw new Exception("Unable to get version");
}
WriteNuspec(nuspecFilePath, version);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
static void WriteNuspec(string path, string version)
{
var lines = File.ReadAllLines(path);
string versionLine = null;
for(var i = 0; i < lines.Length; ++i)
{
var line = lines[i];
if (line.Contains("<version>") && line.Contains("</version>"))
{
var init = line.IndexOf("<version>") + "<version>".Length;
var end = line.IndexOf("</version>");
line = line.Remove(init, end - init);
lines[i] = line.Insert(init, version);
break;
}
}
File.WriteAllLines(path, lines);
}
static void IsFileValid(string file, string extension)
{
if (!File.Exists(file))
{
throw new Exception("Invalid file path: " + file);
}
if (!file.EndsWith(extension))
{
throw new Exception("Invalid file extension: " + file);
}
}
static string GetAssemblyVersion(string path)
{
var lines = File.ReadAllLines(path);
foreach(var line in lines)
{
if(line.Contains("AssemblyVersion") && !line.Contains(".*"))
{
var parts = line.Split('\"');
if (parts.Length != 3)
{
break;
}
return parts[1];
}
}
foreach (var line in lines)
{
if (line.Contains("AssemblyFileVersion") && !line.Contains(".*"))
{
var parts = line.Split('\"');
if (parts.Length != 3)
{
break;
}
return parts[1];
}
}
foreach (var line in lines)
{
if (line.Contains("AssemblyInformationalVersion") && !line.Contains(".*"))
{
var parts = line.Split('\"');
if (parts.Length != 3)
{
break;
}
return parts[1];
}
}
throw new Exception("Unable to get version");
}
如前所述,.bat 文件还包装了 Squirrel.Windows 安装程序的创建。
关于 .bat 的小观察:
- NuspecVersionSetter 是从上面的 .csproj 创建的 .exe
- 此示例假定您的 NuspecVersionSetter.exe 位于 .csproj 中的文件夹内,因此可能需要调整某些路径
- 本例中的Squirrel.Windows版本较旧,请各位多多修改
我使用的 .bat 文件如下:
NuspecVersionSetter ../Properties/AssemblyInfo.cs mynuspec.nuspec
nuget pack
@echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%G in ('dir *.nupkg /b /a-d /od') do (
SET newest=%%G
)
"../../packages/squirrel.windows.1.2.1/tools/Squirrel" --releasify !newest! -g installing.gif
如果对此答案有任何疑问,请在评论中提问。
我想创建一个仅包含我的 nuspec 文件中指定的内容的 nuget 包,但仍然从我的 csproj 中获取版本。为了使用令牌,我必须像这样打包:
nuget pack MyProj.csproj
但是当我这样做时,它会添加一些依赖项并在我的 nuget 包中创建一个不需要的文件夹。我的 nuspec 文件是:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Test</id>
<version>$version$</version>
<title>Test</title>
<authors>Test</authors>
<owners>Test</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Test</description>
<summary>Test</summary>
<releaseNotes>Test</releaseNotes>
<copyright>Test</copyright>
</metadata>
<files>
<file src="bin\Debug\*.dll" target="lib\net45" />
<file src="bin\Debug\MyProj.Wpf.exe" target="lib\net45" />
<file src="bin\Debug\MyProj.Wpf.exe.config" target="lib\net45" />
</files>
</package>
当我 运行 打包命令时,它添加的额外文件是目标中的 MyProj.Wpf.exe="lib\net452"
我可以强制它不添加依赖项和这个额外的文件吗?或者只执行 nuspec 中指定的操作?
我 post 回答这个问题已经有一段时间了。从那以后,我使用了一个对我有用的解决方案,所以我将在这里 post 为任何需要它的人提供。
我创建了一个 .csproj,它修改了 .nuspec 文件并根据 .csproj 的程序集文件设置了它的版本。为了减少手动工作,我创建了一个 .bat 文件,它使用参数调用这个 .exe,并完成了安装程序的创建。我使用 Squirrel.Windows 创建安装程序。
我创建了一个 NuspectVersionSetter.csproj 来设置 nuspec 版本。有很多方法可以实现这个,这里有一个简单的方法:
static void Main(string[] args)
{
try
{
if (args.Length < 2)
{
throw new Exception("Args are not correct");
}
var assemblyFilePath = args[0];
var nuspecFilePath = args[1];
IsFileValid(assemblyFilePath, ".cs");
IsFileValid(nuspecFilePath, ".nuspec");
var version = GetAssemblyVersion(assemblyFilePath);
if (string.IsNullOrEmpty(version))
{
throw new Exception("Unable to get version");
}
WriteNuspec(nuspecFilePath, version);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
static void WriteNuspec(string path, string version)
{
var lines = File.ReadAllLines(path);
string versionLine = null;
for(var i = 0; i < lines.Length; ++i)
{
var line = lines[i];
if (line.Contains("<version>") && line.Contains("</version>"))
{
var init = line.IndexOf("<version>") + "<version>".Length;
var end = line.IndexOf("</version>");
line = line.Remove(init, end - init);
lines[i] = line.Insert(init, version);
break;
}
}
File.WriteAllLines(path, lines);
}
static void IsFileValid(string file, string extension)
{
if (!File.Exists(file))
{
throw new Exception("Invalid file path: " + file);
}
if (!file.EndsWith(extension))
{
throw new Exception("Invalid file extension: " + file);
}
}
static string GetAssemblyVersion(string path)
{
var lines = File.ReadAllLines(path);
foreach(var line in lines)
{
if(line.Contains("AssemblyVersion") && !line.Contains(".*"))
{
var parts = line.Split('\"');
if (parts.Length != 3)
{
break;
}
return parts[1];
}
}
foreach (var line in lines)
{
if (line.Contains("AssemblyFileVersion") && !line.Contains(".*"))
{
var parts = line.Split('\"');
if (parts.Length != 3)
{
break;
}
return parts[1];
}
}
foreach (var line in lines)
{
if (line.Contains("AssemblyInformationalVersion") && !line.Contains(".*"))
{
var parts = line.Split('\"');
if (parts.Length != 3)
{
break;
}
return parts[1];
}
}
throw new Exception("Unable to get version");
}
如前所述,.bat 文件还包装了 Squirrel.Windows 安装程序的创建。
关于 .bat 的小观察:
- NuspecVersionSetter 是从上面的 .csproj 创建的 .exe
- 此示例假定您的 NuspecVersionSetter.exe 位于 .csproj 中的文件夹内,因此可能需要调整某些路径
- 本例中的Squirrel.Windows版本较旧,请各位多多修改
我使用的 .bat 文件如下:
NuspecVersionSetter ../Properties/AssemblyInfo.cs mynuspec.nuspec
nuget pack
@echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%G in ('dir *.nupkg /b /a-d /od') do (
SET newest=%%G
)
"../../packages/squirrel.windows.1.2.1/tools/Squirrel" --releasify !newest! -g installing.gif
如果对此答案有任何疑问,请在评论中提问。