Search Unity

Question Importing Windows Program Icons

Discussion in 'Scripting' started by IsaiahKelly, Jun 26, 2020.

  1. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    I'm trying to import Microsoft Windows program icon files (ICO) into Unity at runtime and convert them to textures.

    In order to do this I need to reference "Microsoft Shell Controls and Automation" for System32 and System.Drawing. I have been able to successfully add these references in Visual Studio 2019 after installing the .NET SDK, but it appears that Unity is rejecting and resetting these references once I switch back to the editor.

    Does anyone know of a workaround or alternative method to extract and import Windows ico files? Could this be fixed by building a plugin (dll) and accessing that instead? I know this is platform specific but I only need it to work on Windows.
     
    Last edited: Jun 27, 2020
  2. Cyber-Dog

    Cyber-Dog

    Joined:
    Sep 12, 2018
    Posts:
    352
    Hey mate, you need to create an mcs file referencing those DLLs.

    Easier to just look at this file rather than Unity docs. They don't make things very clear.
    https://github.com/Harley-Torrisi/AssetCat-Old/blob/master/Assets/mcs.rsp

    Use notepad to make it and SaveAs *AllFiles "mcs.rsp", right in your Assets folder

    ----

    I can't remember how VS handles the mcs file, or if it even does anything with it. But I would first try removing those references from Visual Studio and only add it if Visual Studio gives errors when Unity does not.
     
  3. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    Thanks for the reply @Cyber-Dog.

    I tried adding a csc.rsp file for NET 4.x to my asset folder but it's giving me some parsing errors with "could not be found as a system library". I also believe these global defines mean I won't be able to build to anything but Windows. I actually still want to be able to build to other platforms. I just want to build this code specifically for the Windows version only.

    So I believe a platform dependent plug-in (DLL) combined with platform #define directives in my other scripts is the best option here and I've already successfully got one setup and working now. But thanks for the suggestion. I did not realize that was an option.
     
  4. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
  5. Cyber-Dog

    Cyber-Dog

    Joined:
    Sep 12, 2018
    Posts:
    352
    "I tried adding a csc.rsp file for NET 4.x " what do you mean by this? You should only be targeting specific dll libraries in the "mcs.rsp" file, not a whole framework. Also, double check using "csc.rsp" will work, if that's what I think it is, its for older unity.

    That's not true.
    So your Targeting .net Framework. But compiling the build in Mono. And Mono supports just about everything .Net can do. Mono is cross platform. So you may face issues were a certain system.X class/function does not behave correctly. But that's a different story. And you can always check online where Mono is at with compatibility.

    The file I mentioned earlier was for a project that builds to Win/Lunix/and OS.

    If you don't believe me, or need to see it working in a project that successfully builds. Then download the project from the above link, and have a play. Should be for Unity 2018 LTS version.
     
  6. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    I only mentioned .NET 4.x to explain why I'm using "csc" in the name, since the manual notes that the .rsp file needs to match the compiler being invoked.


    I was actually using IL2CPP but just switched to Mono to see if it would compile faster while developing since it seemed a bit slower than before. I also switched from .NET 4.x profile to .NET Standard 2.0 since this profile only supports features that are cross-platform compatible.

    You'll have to excuse me here a little because I've never dived into .NET and these additional libraries before with Unity, so I'm still learning how everything works. I'll take another look at your example after I've read up on all this some more.
    Thanks for the help!
     
  7. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    I know .NET is a cross-platform library. The issue is I have to target Windows specific libraries too for access the icons (like shell32) and I think that could be a problem. I'm also not sure if referencing those globally even works or means the entire project is now tied to Windows. So a separate plug-in seems safer but I could be completely mistaken. Again, this is all new territory for me.
     
  8. Cyber-Dog

    Cyber-Dog

    Joined:
    Sep 12, 2018
    Posts:
    352
    Ahh, I overlooked your reference to shell32, thinking you were just talking about system.drawing.

    Ok, yea. I reckon you will have a problem with shell.32 on other builds. You could try copying it from the system32 folder into your unity project. But I'm guessing you already tried that? Also, when you use the [DllImport] stage, you can specify the file in your assets folder.

    However. I think your right with the #IF OS check, then just use a different method on another platform.

    Considering that system.drawing will be able to convert .ico files regardless of what platform you are on. Would you consider just using a third-party program to extract all the .ico files from shell32 as a once-off? Then import it to your project. Just found a link on a website, apparently, you can event just use 7-Zip and run extract on the .dll!
     
  9. Cyber-Dog

    Cyber-Dog

    Joined:
    Sep 12, 2018
    Posts:
    352
    Just curious, what's your objective?
    -Do you need to have different OS file types? Like Windows/Lunix/OSX
    -And is there a reason you can't just get al the files you want externaly and import into unity as PNG
     
    Bunny83 likes this.
  10. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    I want to get the icons for use with a custom file browser window. Yea, I know just converting them ahead of time to PNG outside of Unity is easier, but I like the flexibility and challenge of doing it all in Unity. But it may end up being more trouble than it's worth. In which case I'll probably just use some free generic icons instead.
     
  11. annejulietremblay

    annejulietremblay

    Joined:
    Feb 16, 2022
    Posts:
    1
    I'm taking a chance here by asking you this question 2 years later !
    Could you explain exactly how you managed to build a plugin referencing the Shell32 library, and how you were able to use it in Unity? This is exactly what I am trying to do in order to extract file icons as well.
     
  12. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    I simply created a managed plug-in for Unity to handled the process of extracting and converting the ico files for me, based on various C# tutorials and examples I found on the web. Then I just called the plug-in method from Unity, like this.

    Code (CSharp):
    1. #if PLATFORM_STANDALONE_WIN
    2.  
    3.         Texture2D icon = MyPlugin.GetFileIcon(filePath);
    4.  
    5. #endif
    I went with a managed .NET plug-in because I have little experience building native C++ plug-ins for Unity. However the latter would be more ideal here, as calling C++ methods from C# is painful and so I kind of gave up on it because of that. So I strongly discourage even trying to do this if you don't have much experience creating plug-ins and/or if getting the ico files is not absolutely necessary. As it will likely be more trouble than it's worth.
     
    Bunny83 likes this.