4

这是我的课

  [ProtoContract]
            internal class Powershellresults
            {
                internal Powershellresults()
                {
                }
                [ProtoMember(1)]
                public Collection<PSObject> PsObjects { get; set; }
                [ProtoMember(2)]
                public string Script { get; set; }
                [ProtoMember(3)]
                public string Viewname { get; set; }
            }

但是当我尝试序列化它时,我得到 No serializer defined for type: System.Management.Automation.PSObject

private byte[] SerializeResults(Powershellresults obj)
        {
            byte[] data;
            using (var ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize(ms, obj);
                data = ms.ToArray(); ;
            }
            return data;
        }

PsObject 是 System.Management.Automation 的一部分

我可以解决这个问题并实际序列化这个集合吗?

更新:通过添加到我的序列化方法

RuntimeTypeModel.Default.Add(typeof(PSObject), true);

我可以让它序列化-但是一旦序列化它就会丢失大部分字段我如何让它“克隆”原始对象以保留其所有字段和属性?

编辑

我想到了!我心想,Powershell 必须能够序列化它的对象,因为您可以轮询远程机器——否则它如何能够在机器之间发送 PSObject——它确实如此!(呜呜!!!!)

好吧,我找到了一篇描述这一点的文章,并找到了我的关键字System.Management.Automation.PSSerializer

Collection<PSObject> PSCol = Powershell.Invoke(); 
string SerializedCollection = PSSerializer.Serialize(PSCol);

//序列化到XML完成!

然后使用 Protobuf-net 或任何其他方法对字符串进行序列化...

反序列化有点尴尬,但对于反序列化使用来说非常简单:使用 Protobuf 反序列化字符串,然后...

PSObject obj = PSSerializer.Deserialize(DeserializedString) as PSObject;

Collection<PSObject> DeserializedCollection = new Collection<PSObject>(((ArrayList)obj.ImmediateBaseObject).Cast<PSObject>().ToArray());

就是这样..

4

2 回答 2

4

我想到了!我心想,Powershell 必须能够序列化它的对象,因为您可以轮询远程机器——否则它如何能够在机器之间发送 PSObject——它确实如此!(呜呜!!!!)

好吧,我找到了一篇描述这一点的文章,并找到了我的关键字System.Management.Automation.PSSerializer

Collection<PSObject> PSCol = Powershell.Invoke(); 
string SerializedCollection = PSSerializer.Serialize(PSCol);

//序列化到XML完成!

然后使用 Protobuf-net 或任何其他方法对字符串进行序列化...

反序列化有点尴尬,但对于反序列化使用来说非常简单:使用 Protobuf 反序列化字符串,然后...

PSObject obj = PSSerializer.Deserialize(DeserializedString) as PSObject;

Collection<PSObject> DeserializedCollection = new Collection<PSObject>(((ArrayList)obj.ImmediateBaseObject).Cast<PSObject>().ToArray());

就是这样..

于 2013-11-07T09:15:46.580 回答
1

PSObject太模糊,无法成为一个好的序列化候选者(尤其是,它是一个dynamic提供者等);我强烈建议您构建一个定义明确的DTO 模型,即

[ProtoMember(1)]
public Collection<SomeTypeThatYouOwn> Items {get;set;}

whereSomeTypeThatYouOwn具有有意义的属性等。您始终可以转换为/从SomeTypeThatYouOwn接近序列化/反序列化 setp。PSObject基本上是一个属性包,并且效果不佳,因为 protobuf 不包含任何元数据(您需要提前知道数据的形状才能有意义地对其进行反序列化)。

于 2013-11-06T13:01:09.393 回答