我试图使用格式在C#项目,使用格式净,我不知道什么是最好的方式来组织这个成Visual Studio项目的结构。

当使用手动protogen工具产生的代码进入,生活似乎很容易,但这感觉不正确的。

我会喜欢的.原文件被认为是主要来源码文件,产生C#文件作为一个副产品,但在此之前,C#编译器获取的参与。

选项似乎是:

  1. 定义的工具,用于原工具(虽然我看不到从哪里开始有)
  2. 预先建立的步骤(调protogen或一批文件,该文件不会)

我已经挣扎2)所述的,因为它不断给我,"本系统找不到指定的文件",除非我用绝对路径(并且我不喜欢强迫项目的明确的位置).

是否有一个《公约》(尚未)为了这个?


编辑: 根据@乔恩的评论,我重新尝试的预先建立一步的方法及使用这一(protogen的位置硬编码为现),使用谷歌地址簿的例子:

c:\bin\protobuf\protogen "-i:$(ProjectDir)AddressBook.proto" 
       "-o:$(ProjectDir)AddressBook.cs" -t:c:\bin\protobuf\csharp.xslt

Edit2: 把@jon的建议,以尽量减少建设时不处理。原始文件,如果他们还没有改变,我被撞在一起的一个基本工具请检查我的(这也许可以扩大到一个完整的定制工具):

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
有帮助吗?

解决方案

作为一个扩展的肖恩的代码,我高兴地宣布,格式网现在已经Visual Studio一体化的方式定义的工具。Msi安装可以从 项目页.更完整的信息在这里: 格式-net;现在有加入的逆戟鲸.

Visual Studio with protobuf-net as a Custom Tool

其他提示

叫一个预建立一步,但使用项目变量(例如 $(ProjectPath))创建的绝对文件没有让他们实际上在你的解决方案似乎是一个合理的投注我的。

有一件事你也许想要考虑的基础上,我过去经验的代码发电机:你可能要写一个包装protogen其产生的代码不同的位置,然后检查是否有新产生的代码是一样的老码,并不复盖它如果是这样。这种方式Visual Studio会意识到什么也没有改变,而不是强迫该项目须重建这一切建立次 对于我的过去。

或者,你可以保持一个md5hash。原文件的最后一次protogen执行,并且只有执行protogen如果.原始文件已经改变了-至少要做到每个建立!

谢谢你提出这一问题,虽然它清楚地表明我应该作出一种方法来使这是一个简单的预先建立的步骤对于我自己的港口。

添加以下预先建立的事件来项目的设置产生的C#文件只有当的。原始文件已经改变。只是替换 YourFile 名称的基名字的你.原文件。

cd $(ProjectDir) && powershell -Command if (!(Test-Path YourFile.proto.cs) -or (Get-Item YourFile.proto).LastWriteTimeUtc -gt (Get-Item YourFile.proto.cs).LastWriteTimeUtc) { PathToProtoGen\protogen -i:YourFile.proto -o:YourFile.proto.cs }

这一工作的任何最新版本的Visual Studio,不同的格式-net定建立的工具,它不支持Visual Studio2012年或Visual Studio2013年,根据问题 338413.

这增加了有关项目文件。

优势、增量建立的。

缺点,需要编辑手动时增加文件。

<ItemGroup>
    <Proto Include="Person.proto" />
    <Compile Include="Person.cs">
        <DependentUpon>Person.proto</DependentUpon>
    </Compile>
</ItemGroup>
<PropertyGroup>
    <CompileDependsOn>ProtobufGenerate;$(CompileDependsOn)</CompileDependsOn>
</PropertyGroup>
<Target Name="ProtobufGenerate" Inputs="@(Proto)" Outputs="@(Proto->'$(ProjectDir)%(Filename).cs')">
    <ItemGroup>
        <_protoc Include="..\packages\Google.Protobuf.*\tools\protoc.exe" />
    </ItemGroup>
    <Error Condition="!Exists(@(_protoc))" Text="Could not find protoc.exe" />
    <Exec Command="&quot;@(_protoc)&quot; &quot;--csharp_out=$(ProjectDir.TrimEnd('\'))&quot; @(Proto->'%(Identity)',' ')" WorkingDirectory="$(ProjectDir)" />
</Target>

好吧,那给了我一个想法(一些有关重新发明轮子)...

  • 创建一个简单的Makefile。麦喜欢的东西
.SUFFIXES : .cs .proto

.proto.cs:
    protogen\protogen.exe -i:$? -o:$@ -t:protogen\csharp.xlst

(显然,不要忘记替代路径protogen和c#.xlst)。 重要的是--protogen\protogen.exe 命令开始从签字,不是8个空间

  • 如果你不想要指定文件需要建立所有时间,你可能用的东西喜欢
.SUFFIXES : .cs .proto

all: mycs1.cs myotherfile.cs

.proto.cs:
    protogen\protogen.exe -i:$? -o:$@ -t:protogen\csharp.xlst
  • 在预定建立一步加
cd $(ProjectDir) && "$(DevEnvDir)..\..\vc\bin\nmake" /NOLOGO -c -f Makefile.mak mycs1.cs myotherfile.cs

或者,如果你让你的路径,可以使用

cd $(ProjectDir) && nmake /NOLOGO -c -f Makefile.mak mycs1.cs myotherfile.cs

我附上一个快速和肮脏的Visual Studio定工具包装ProtoGen.exe 谷歌的代码页这个问题(http://code.google.com/p/protobuf-net/issues/detail?id=39).这使得加入。原文件C#项目非常容易的。

看到自述的附件的更多信息。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top