문제

C# 프로젝트에서 Protobuf를 사용하여 Protobuf-Net을 사용하려고 노력하고 있으며이를 Visual Studio Project 구조로 구성하는 가장 좋은 방법이 무엇인지 궁금합니다.

프로토겐 도구를 수동으로 사용하여 C#에 코드를 생성 할 때는 Life가 쉬운 것처럼 보이지만 기분이 좋지 않습니다.

.proto 파일이 기본 소스 코드 파일로 간주되어 C# 파일을 부산물로 생성하지만 C# 컴파일러가 참여하기 전에.

옵션은 다음과 같습니다.

  1. 프로토 도구를위한 맞춤형 도구 (어디서부터 시작 해야할지 볼 수는 없지만)
  2. 사전 건축 단계 (Protogen 또는 배치 파일 호출)

나는 절대 경로를 사용하지 않는 한 "시스템이 지정된 파일을 찾을 수 없다"는 "시스템이 지정된 파일을 찾을 수 없다"는 위의 2)로 고생했다 (그리고 프로젝트가 명시 적으로 위치하도록 강요하는 것을 좋아하지 않는다).

이것에 대한 컨벤션이 있습니까?


편집하다:@Jon의 의견을 바탕으로 Google의 주소 북 예제를 사용하여 건축 사전 단계 방법을 다시 만들고 이것 (현재로서는 Protogen의 위치 하드 코드)을 사용했습니다.

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

edit2 :.proto 파일이 변경되지 않은 경우 빌드 타임을 최소화하기 위해 @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
도움이 되었습니까?

해결책

Shaun 코드의 확장으로 Protobuf-Net은 이제 사용자 정의 도구를 통해 Visual Studio 통합을 가지고 있음을 발표하게되어 기쁩니다. MSI 설치 프로그램은 프로젝트 페이지. 보다 완전한 정보는 다음과 같습니다. protobuf-net; 이제 추가 오크가 있습니다.

Visual Studio with protobuf-net as a Custom Tool

다른 팁

사전 건축 단계를 호출하지만 프로젝트 변수를 사용합니다 (예 : $(ProjectPath)) 실제로 솔루션에 들어 가지 않고 절대 파일 이름을 만드는 것은 나에게 합리적인 내기처럼 보일 것입니다.

코드 생성기의 과거 경험을 바탕으로 고려해야 할 한 가지 : 다른 위치에 코드를 생성하는 Protogen 용 래퍼를 작성하고 새로 생성 된 코드가 이전 코드와 동일하고 동일한 지 확인합니다. 그렇다면 그것을 덮어 쓰지 않습니다. 그런 식으로 Visual Studio는 아무것도 변경되지 않았고 프로젝트가 재건되지 않도록 강요하지 않을 것입니다 - 이것은 빌드 타임을 줄였습니다. 극적으로 과거에 나를 위해.

또는 마지막으로 Protogen이 실행 된 경우 .proto 파일의 MD5 해시를 유지하고 .proto 파일이 변경된 경우에만 프로토 겐 만 실행할 수 있습니다. 각 빌드에서 수행 할 수 없습니다!

그래도 이것을 질문으로 제기해 주셔서 감사합니다. 이는 이것을 내 포트를위한 쉬운 사전 건설 단계로 만들 수있는 방법을 알아야합니다.

.proto 파일이 변경된 경우에만 C# 파일을 생성하기 위해 프로젝트 설정에 다음 사전 제작 이벤트를 추가하십시오. 그냥 교체하십시오 YourFile .proto 파일의 기본 이름 이름이 있습니다.

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 2012 또는 Visual Studio 2013을 지원하지 않는 Protobuf-Net Custom-Build Tool과 달리 최근 버전의 Visual Studio에서 작동합니다. 338 그리고 413.

이것을 관련 프로젝트 파일에 추가하십시오.

장점, 증분 빌드.

단점은 파일을 추가 할 때 수동으로 편집해야합니다.

<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.mak을 만들어냅니다
.SUFFIXES : .cs .proto

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

(분명히, Protogen 및 Csharp.xlst 로의 경로를 대체하는 것을 잊지 마십시오). 중요 - protogen protenge.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

또는 경로에 nmake가있는 경우 사용할 수 있습니다.

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

이 문제에 대한 Google 코드 페이지에 Protogen.exe 주변의 빠르고 더러운 비주얼 스튜디오 사용자 정의 래퍼를 첨부했습니다 (http://code.google.com/p/protobuf-net/issues/detail?id=39). 따라서 C# 프로젝트에 .proto 파일을 추가하는 것은 매우 쉽습니다.

자세한 내용은 첨부 파일의 readme를 참조하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top