Harmony: InvalidCastException on reverting the patches

I have a mod for the Cities: Skylines game. I use Harmony version 1.1.0 for creating a couple of patches for the game methods.

I activate my patches using attributes:

myHarmonyInstance.PatchAll(Assembly.GetExecutingAssembly());

But before doing that, I want to ensure that the methods are only patched once. The game might call the mod’s initialization methods multiple times (unexpectedly), so I created a kind of a clean-up before running my patches:

foreach (MethodBase method in harmonyInstance.GetPatchedMethods().ToList())
{
    harmonyInstance.RemovePatch(method, HarmonyPatchType.All, "my-custom-id");
}

Of course, I want to remove only my patches, hence I use the overload that specifies my custom ID.

But in case there are already some patches that are applied by other developers (and maybe using other Harmony versions), I get an exception:

System.InvalidCastException: Cannot cast from source type to destination type.
at Harmony.PatchInfoSerialization.Deserialize (System.Byte[] bytes)
at Harmony.HarmonySharedState.GetPatchInfo (System.Reflection.MethodBase method)
at Harmony.PatchProcessor.Unpatch (HarmonyPatchType type, System.String harmonyID) 
at Harmony.HarmonyInstance.RemovePatch 

Note: this also happens when I clean-up the patches on unloading the mod, because I use the same foreach loop with RemovePatch calls.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 16 (9 by maintainers)

Most upvoted comments

I’ve had a user of my mod RandomTrainTrailers experience the same issue, but unfortunately I’ve not been able to reproduce it yet.

Here’s my user’s error

The Mod C:\Games\Steam\steamapps\workshop\content\255710\870291141 [0Harmony.dll, RandomTrainTrailers.dll] has caused an error [ModException]

Details:
System.InvalidCastException: Cannot cast from source type to destination type.
at Harmony.PatchInfoSerialization.Deserialize (System.Byte[] bytes) [0x00000] in <filename unknown>:0 
at Harmony.HarmonySharedState.GetPatchInfo (System.Reflection.MethodBase method) [0x00000] in <filename unknown>:0 
at Harmony.HarmonyInstance+<>c__DisplayClass13_0.<VersionInfo>b__0 (System.Reflection.MethodBase method) [0x00000] in <filename unknown>:0 
at Harmony.CollectionExtensions.Do[MethodBase] (IEnumerable`1 sequence, System.Action`1 action)[0x00000] in <filename unknown>:0 at Harmony.HarmonyInstance.VersionInfo (System.Version

Also I noticed the MSDN page for Assembly.Load(byte[]) does indicate it will always return “a new Assembly object with its own mapping” and since C:S uses that for loading it might be related to the issue we’re having. I’ve made a small mod that logs loaded mods and assemblies in the current AppDomain when loading the level, maybe that can shed some light on the duplicate loading that seems to be happening.

So yeah, not that much in the way of possible fixes but it does show that multiple people are having issues. And since Harmony is a pretty good replacement for basic detouring it’d be a shame if we can’t find a fix or workaround for this.