15

参照されたdllを使用したC#ソリューションがあります(同じ.NetバージョンのC#も)。ソリューションをビルドして結果のexeを実行すると、exeと参照されたdllをマージせずに、すべて正常に動作します。

これらを1つのexeにマージしたいと思います。ILMerge を実行すると、すべて正常に動作しているように見えます。私はexeを実行しようとしましたが、参照されたdllで定義されたオブジェクトを逆シリアル化しようとするまで、問題なく実行されているようです。

using (Stream fstream = new FileStream(file_path, FileMode.Open))
{
    BinaryFormatter bf = new BinaryFormatter();
    return bf.Deserialize(fstream) as ControlledRuleCollection; 
    // throws unable to find assembly exception
}

ここに欠けているILMergeオプションはありますか?

4

10 に答える 10

46

これを行うには、逆シリアル化が発生する前にアセンブリ名を変更する SerializationBinder サブクラスを作成して追加します。

sealed class PreMergeToMergedDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        Type typeToDeserialize = null;

        // For each assemblyName/typeName that you want to deserialize to
        // a different type, set typeToDeserialize to the desired type.
        String exeAssembly = Assembly.GetExecutingAssembly().FullName;


        // The following line of code returns the type.
        typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
            typeName, exeAssembly));

        return typeToDeserialize;
    }
}

次に、逆シリアル化するときに、これを BinaryFormatter に追加します。

BinaryFormatter bf = new BinaryFormatter();
bf.Binder = new PreMergeToMergedDeserializationBinder();
object obj = bf.Deserialize(ms);
于 2012-01-25T23:41:41.533 に答える
7

DLL内でオブジェクトをシリアル化してから、すべてのアセンブリをILMergeとマージし、そのオブジェクトを逆シリアル化しようとしているようです。これは単に機能しません。バイナリシリアル化の逆シリアル化プロセスは、元のDLLからオブジェクトの型を読み込もうとします。このDLLはILMergeの後に存在しないため、逆シリアル化は失敗します。

シリアル化と逆シリアル化のプロセスは、マージ前またはマージ後の両方で動作する必要があります。混ぜることはできません

于 2011-03-02T16:39:50.893 に答える
3

別のアセンブリからシリアル化してから、別のアセンブリ(または同じアセンブリの新しいバージョン)で逆シリアル化しようとした可能性があります。

ここでいくつかの議論

于 2011-03-02T16:25:24.310 に答える
2

この問題を抱えていて、別のアセンブリから逆シリアル化しようとしている人のために、問題のオブジェクト型の共有名前空間を持つ小さな「BindChanger」クラスを使用して、この解決策を見つけました。 https://www.daniweb.com/programming/software-development/threads/339638/deserializing-in-a-different-assembly

于 2018-08-01T14:05:06.450 に答える
0

アセンブリを既存のものにマージする場合 (たとえば、すべての DLL を EXE にマージする場合)、この回答で提案されているソリューションを使用できます。

// AssemblyInfo.cs for My.exe
[assembly: TypeForwardedTo(typeof(SomeTypeFromMergedDLL))]

これは少なくとも、マージ前のデシリアライズには機能します。IL-Merge も引き続きパスします。同じアセンブリの型への型転送でコンパイルできなくても...

シリアル化がマージ後に機能する場合は、まだ試していません。しかし、私は答えを更新し続けます。

于 2011-08-05T07:32:19.833 に答える
0
    public sealed class DeserializationBinder : SerializationBinder
{
    private readonly string _typeName;
    private readonly Assembly _assembly;
    public DeserializationBinder(Assembly assembly, string typeName)
    {
        _typeName = typeName;
        _assembly = assembly;
    }

    public override Type BindToType(string assemblyName, string typeName)
    {
        Type typeToDeserialize = null;
        if (!assemblyName.Contains("System") && !assemblyName.Contains("mscorlib"))
        {
            String currentAssembly = _assembly.FullName;
            assemblyName = currentAssembly;
            typeName = _typeName;
        }
        typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
            typeName, assemblyName));
        return typeToDeserialize;
    }
}
于 2014-06-01T17:08:00.830 に答える