Custom script icon by code inside assembly

I’m trying to change the icon shown on inspector/project view for custom types derived of MonoBehaviour. I have those types inside a compiled assembly (i.e. MyAssembly.MyScript).

I’ve managed to load a custom icon by placing it at the following path Gizmos/MyScript Icon.png. But I don’t want the icons to be there, as I’m embedding them into the assembly (they are base64’d on code, so I load them at recompilation). Any hint on how to load them properly? Or even an explanation on how Unity load those? I’ve been digging the assemblies for a while and the closest I’ve got is AssetPreview.GetMiniThumbnail (obj), which is defined on unmanaged-code land (i.e. C++), and only gives me the image but doesn’t let me change it.

You can change them either via the editor or via manipulating the meta files yourself (go for the later if there are a lot of scripts in your assembly).
To show the differences, I will explain the process for assembly scripts as well as non-assembly scripts.

Non assembly scripts

The usual way to change a scripts icon is by selecting the script in the project view to see it in the inspector. On the top left is the default script icon with a dropdown indicator. Click on that to get various options as well as the option to select a custom image, which does not have to reside in any special directory.

This changes the meta file to reflect the new icon as such:

fileFormatVersion: 2
guid: 6543a02a4c6aac747a980a5d43f0b13b
...
MonoImporter:
  serializedVersion: 2
  ...
  icon: {fileID: 2800000, guid: 659304581cc9f3c4aa2a7f1942ceac20, type: 3}

Notice the icon: entry.

Assembly scripts

Scripts inside an assembly can be viewed in the project view and inspector too, but, for some reason, do not have that dropdown. This makes sense, as scripts from assembly do not have their own meta files.

But the assembly itself does!

A trick to change the icon via the editor is by opening the the “Gizmo” dropdown. For the script to even appear there it must either already have a custom icon or have an OnDrawGizmos() method.
If it doesn’t, you may just add an emtpy OnDrawGizmos() method temporarily (and remove it after you have set an icon as it will appear from there on anyway).
There is a little dropwdown next to your script which gives you the exact same menu to change the icon (and it works flawlessly). Unity may get stuck a little after changing it, as it reimports the meta data about the whole assembly.

The changes are reflected in the assemblys meta file as such:

fileFormatVersion: 2
guid: c5e7423a261e0bb41b66c0570cb04b0a
...
PluginImporter:
  serializedVersion: 1
  iconMap:
    Fully.Qualified.Name.Track: {fileID: 2800000, guid: 659304581cc9f3c4aa2a7f1942ceac20,
      type: 3}
  executionOrder:
    FirstScene: -32000

Notice the iconMap: section. Each entry has as key the fully qualified name of the class (its namespaces, containing classes’ names and its own class name, just like you would import it) and as value the reference to the asset you want to use (which can be found easily with existing asset database and editor classes form unity)