I'm trying to send a protobuf message to a child process. Deserialization works fine in the parent, like this:
var deserialized = Serializer.Deserialize(typeof(ChildProcessTestMessage), new MemoryStream(new byte[] { 8, 1 }));
[ProtoContract]
public class ChildProcessTestMessage
{
[ProtoMember(1)]
public int Int { get; set; }
}
I have hardcoded the bytes 0x0801 in this sample code and in the child process in order to make sure that the bytes are correct. I obtained these bytes by serializing a test instance.
Deserialization code in the child is different in one important way: The parent communicates the type to use for deserialization over a pipe. The type can be loaded successfully in the child. I then call protobuf-net like this:
var (assemblyName, typeName, methodName, argument) = protocol.ReadExecuteMethod();
Assembly assembly;
try
{
var name = new AssemblyName(assemblyName);
assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.Combine(Directory.GetCurrentDirectory(), name.Name + ".dll"));
}
catch (Exception ex)
{
//...
}
var type = assembly.GetType(typeName);
var method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public);
var parameterType = method.GetParameters().Single().ParameterType;
var message = Serializer.Deserialize(new MemoryStream(new byte[] { 8, 1 }), parameterType);
The child reports the following error:
Failed to invoke method 'TestMethod': ProtoBuf.ProtoException: Invalid wire-type (Varint); this usually means you have over-written a file without truncating or setting the length; see Using Protobuf-net, I suddenly got an exception about an unknown wire-type at ProtoBuf.ProtoReader.State.ThrowProtoException(String message) in //src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:line 764
at ProtoBuf.ProtoReader.State.ThrowWireTypeException() in //src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:line 758
at ProtoBuf.Internal.PrimaryTypeProvider.ProtoBuf.Serializers.ISerializer<System.Type>.Read(State& state, Type value) in //src/protobuf-net.Core/Internal/PrimaryTypeProvider.Primitives.cs:line 292 at ProtoBuf.ProtoReader.State.g__ReadFieldOne|102_0[T](State& state, SerializerFeatures features, T value, ISerializer1 serializer) in /_/src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:line 1075 at ProtoBuf.ProtoReader.State.ReadAsRoot[T](T value, ISerializer
1 serializer) in //src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:line 1059
at ProtoBuf.ProtoReader.State.DeserializeRoot[T](T value, ISerializer`1 serializer) in //src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:line 1036
at ProtoBuf.Serializer.Deserialize[T](Stream source, T value, Object userState, Int64 length) in //src/protobuf-net/Serializer.Deserialize.cs:line 43 at ChildProcess.Program.Main(String[] args) in ...\Program.cs:line 324
I have added debug output to make sure that parameterType == typeof(ChildProcessTestMessage)
.
I'm currently at a loss at why it's not working and how to debug this. There must be a difference in the child process somehow but I have no lead what it could be.
One idea was that maybe assembly loading is different. Could this manifest as this kind of failure?
This is on .NET Core 5.
I'd appreciate your help.
Update: I have now hardcoded a copy of that proto contract into the child. Everything coming over the wire is now ignored. The deserialization call looks like in the parent. Same error as before...
The child process exe is a project in this solution. I'm invoking it from a unit test project, and it lives in the same directory as the unit test DLL and current directory. Could this mess up the child? There are lots of files there which the child maybe didn't expect.