我正在尝试在 C# 项目中使用 protobuf,使用 protobuf-net,并且想知道将其组织到 Visual Studio 项目结构中的最佳方法是什么。
当手动使用 protogen 工具将代码生成到 C# 中时,生活似乎很轻松,但感觉并不正确。
我希望 .proto 文件被视为主要源代码文件,生成 C# 文件作为副产品,但在 C# 编译器参与之前。
选项似乎是:
- 原型工具的自定义工具(虽然我看不到从哪里开始)
- 预构建步骤(调用 protogen 或执行此操作的批处理文件)
我一直在上面的 2)中挣扎,因为它一直给我“系统找不到指定的文件”,除非我使用绝对路径(而且我不喜欢强制明确定位项目)。
是否有一个约定(还)?
编辑: 根据@jon的评论,我重试了预构建步骤方法并使用了这个(protogen的位置现在硬编码),使用谷歌的地址簿示例:
c:\bin\protobuf\protogen "-i:$(ProjectDir)AddressBook.proto"
"-o:$(ProjectDir)AddressBook.cs" -t:c:\bin\protobuf\csharp.xslt
Edit2: 采纳@jon 的建议,通过不处理 .proto 文件(如果它们没有更改)来最小化构建时间,我已经拼凑了一个基本工具来检查我(这可能会扩展到一个完整的自定义构建工具):
using System;
using System.Diagnostics;
using System.IO;
namespace PreBuildChecker
{
public class Checker
{
static int Main(string[] args)
{
try
{
Check(args);
return 0;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return 1;
}
}
public static void Check(string[] args)
{
if (args.Length < 3)
{
throw new ArgumentException(
"Command line must be supplied with source, target and command-line [plus options]");
}
string source = args[0];
string target = args[1];
string executable = args[2];
string arguments = args.Length > 3 ? GetCommandLine(args) : null;
FileInfo targetFileInfo = new FileInfo(target);
FileInfo sourceFileInfo = new FileInfo(source);
if (!sourceFileInfo.Exists)
{
throw new ArgumentException(string.Format(
"Source file {0} not found", source));
}
if (!targetFileInfo.Exists ||
sourceFileInfo.LastWriteTimeUtc > targetFileInfo.LastAccessTimeUtc)
{
Process process = new Process();
process.StartInfo.FileName = executable;
process.StartInfo.Arguments = arguments;
process.StartInfo.ErrorDialog = true;
Console.WriteLine(string.Format(
"Source newer than target, launching tool: {0} {1}",
executable,
arguments));
process.Start();
}
}
private static string GetCommandLine(string[] args)
{
string[] arguments = new string[args.Length - 3];
Array.Copy(args, 3, arguments, 0, arguments.Length);
return String.Join(" ", arguments);
}
}
}
我的预构建命令现在是(全部在一行上):
$(SolutionDir)PreBuildChecker\$(OutDir)PreBuildChecker
$(ProjectDir)AddressBook.proto
$(ProjectDir)AddressBook.cs
c:\bin\protobuf\protogen
"-i:$(ProjectDir)AddressBook.proto"
"-o:$(ProjectDir)AddressBook.cs"
-t:c:\bin\protobuf\csharp.xslt