Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate theming from net461 to net50 #9191

Closed
NikolayXHD opened this issue May 10, 2021 · 29 comments
Closed

Migrate theming from net461 to net50 #9191

NikolayXHD opened this issue May 10, 2021 · 29 comments
Assignees

Comments

@NikolayXHD
Copy link
Member

Beginning of discussion: #8522 (comment)

@RussKie
Copy link
Member

RussKie commented May 20, 2021

Have you seen https://github.com/Microsoft/Detours?

@RussKie
Copy link
Member

RussKie commented May 20, 2021

@NikolayXHD
Copy link
Member Author

Thank you, will look at it the coming weekend

@NikolayXHD
Copy link
Member Author

@NikolayXHD if you run with the Managed Debug Assistants turned on in VS, do they flag any kind of interop issues? It may be that a calling convention or argument marshalling is incorrectly specified, and that it worked under .NET Framework but fails under .NET Core.

Thank you, good to know it exists! Gave it a shot, unfortunately it no new information so far.
The program loads a bunch of DLLs, then ExecutionEngineException, nothing intercepted or outputted in between

image

@NikolayXHD
Copy link
Member Author

NikolayXHD commented Jun 5, 2021

...and https://github.com/citronneur/detours.net?

detours.net should be able to achieve what we need, not directly though.

.\DetoursNetRuntime myplugin.dll process_to_inject_hooks_into.exe

is not what we want. The goal would be to achieve hooking "from inside" a .net process by learning from detours.net codebase.

Plan

  1. Make sure the detours.net suggested approach is able to hook the theming api functions we need.
    At this point, if successfull, we at least know that detours can do the job, with or without detours.net.
  2. Achieve hooking from within the process.

point 1. Should be relatively straightforward
point 2. May prove difficult, however, the fact that detours.net codebase is not huge at all, suggests that using original detours from .NET is doable with moderate effort.

@sharwell
Copy link
Member

sharwell commented Jun 5, 2021

is there a list of the APIs that are currently hooked for theming?

@NikolayXHD
Copy link
Member Author

8 methods, see Win32ThemeHooks.InstallHooks

@KindDragon
Copy link
Contributor

Related WinForms issue dotnet/winforms#5166

@macsux
Copy link

macsux commented Nov 3, 2022

I had success getting CoreHook to work with .net core as replacement for easyhook. https://github.com/unknownv2/CoreHook

@yenic
Copy link

yenic commented Nov 3, 2022

CoreHook looks interesting but it does appear that WinForms theming is on the roadmap for .NET 8. dotnet/winforms#5166 (comment)

If they implement it, that will be November 2023. Unless someone volunteers to build in CoreHook and support it, we can probably count on 2024. I would just wait this one out, it's one year without dark theme in Git Extensions 4.0+.

@RussKie
Copy link
Member

RussKie commented Nov 4, 2022

Related WinForms issue dotnet/winforms#5166

I wouldn't count on this in the foreseeable future (if at all). dotnet/winforms#7641 is significantly more likely to occur, though I'd be surprised if it lands in .NET 8 timeframe.

@pmiossec
Copy link
Member

pmiossec commented Nov 7, 2022

I had success getting CoreHook to work with .net core as replacement for easyhook. https://github.com/unknownv2/CoreHook

@macsux Do you have some more information on that? Documentation ? An example repository doing it? Or is it a drop-in replacement for EasyHook?

@macsux
Copy link

macsux commented Nov 7, 2022

It's pretty much a drop in replacement from what I remember. Here's me using it in one of the projects: https://github.com/macsux/cf-buildpack-windows-services/blob/master/src/WindowsServicesBuildpack/ScimControllerInjector.cs

@spdr870
Copy link
Member

spdr870 commented Nov 8, 2022

It looked like a very simple replacement. Just replace LocalHook with CoreHook.LocalHook in Win32ThemeHooks. (after adding the nuget packages and the native dll's) Still, my attempt to replace EasyHook with CoreHook failed with this exception:
An unhandled exception of type 'System.ExecutionEngineException' occurred in Unknown Module.

@FenPhoenix
Copy link

Still, my attempt to replace EasyHook with CoreHook failed with this exception:
An unhandled exception of type 'System.ExecutionEngineException' occurred in Unknown Module.

Hello, I'm the author of another app that uses hooking as part of WinForms theming, and I ran into this same ExecutionEngineException issue when trying to move from Framework 4.7.2 to .NET 7. I determined the exception comes from the GetSysColor() hook only, so I created an issue here: dotnet/runtime#78086

As you can see from the reply, it's apparently because GetSysColor() is set up with a [SuppressGCTransition] attribute in the newer .NETs, and that breaks the hook and causes the ExecutionEngineException. Here's the code. It looks like just a normal p/invoke setup that the runtime can call explicitly, so I'm not sure why putting the attribute on just that one definition would affect all calls to the native GetSysColor() function even from native controls, but it seems to. I'm no expert on how this sort of thing works so I dunno. I'm at a loss for any way to get around it, but at least I thought I'd save others the trouble I went through of trying to figure it out.

@yenic
Copy link

yenic commented Nov 13, 2022

It sounds like CoreHook isn't going to work after reading that thread (dotnet/runtime#78086). Seems like the best hope is dotnet/winforms#7641 for this issue, as RussKie originally suggested.

@Eneong
Copy link

Eneong commented Nov 16, 2022

What if as a temporary solution before .net8 release you were to create a separate build with the dark theme? Something tells me that it shouldnt be too hard to implement

@RussKie
Copy link
Member

RussKie commented Feb 12, 2023

Closing as it is currently technically not possible, see #9191 (comment).

@RussKie RussKie closed this as completed Feb 12, 2023
@Cyber1000
Copy link

Would this work? (Disclaimer: not tested by me)

@gerhardol
Copy link
Member

Crossposting some suggestions: #10312 (comment)

@popara96
Copy link

Any news regarding this discussion, with the comment @gerhardol mentioned?

@gerhardol
Copy link
Member

No workaround for the hooking found.
No support for theming that I have seen also in the upcoming.net8

@RussKie
Copy link
Member

RussKie commented Mar 5, 2024

The theming support may be coming in .NET 9 it seems: dotnet/winforms#10985

@KlausLoeffelmann
Copy link

KlausLoeffelmann commented Mar 6, 2024

@RussKie: If that's all right, I'd ping you once I think, you could "try" it.

I would be very much interested in the experience to enable dark mode for whatever custom controls you guys have. For all the normal stuff, it should be easy to migrate.

For now, you'd just use...

image

Later I guess we should have an additional project setting, so that also the Designer could pick up that color scheme, and then we generate and inject via ApplicationConfiguration.Initialize(). If you pick Inherits, then the System setting is applied wherever possible. (Problems are TabControl - not natively themable at all, and neither are MonthCalendar and therefore DateTimePicker). Inherits here is a "logical ambient" property, means, the idea is, that any control with that setting looks at its parent, a top-level control without a parent would look at Application.DefaultDarkMode and the Application using Inherits would look at the System.

So, for styling individual (custom) controls: If it's more than ForeColor and BackColor (and since I am working with Git Extensions, I know there is quite some coloring going on), the principal approach would be:

  1. Test, if dark mode is in the current context available by using [Contropl.]IsDarkModeEnabled.
  2. Access the Dark Mode/Current palette for the entire application, by using Application.SystemColors.[SystemColorName].
  3. Get the color from there and style the control with it. This way, the color assignment should then work both for dark- and light mode, since that palette reflects the current setting (and we also have then a hook for future extensions).

And, as usual, Igor and I do our usual "Naming and Convention Dance", so, API names might not be cast in stone quite yet.

Looking very much forward for feedback, but also keep in mind: The MVP Summit is coming up, so I'll be going dark (pun intended) for next 2 weeks.

@gerhardol
Copy link
Member

@RussKie Is this ready to be tried for GE?

@RussKie
Copy link
Member

RussKie commented May 25, 2024

@RussKie Is this ready to be tried for GE?

¯\_(ツ)_/¯ I'm no longer part of the Windows Forms team, and I have a basic understanding of what the team is working on.
That PR is still in draft, so the answer to your question is "no".

@gerhardol
Copy link
Member

dotnet/winforms#11857 has been merged, so there is some kind of dark mode expected in .NET9

@Bush-cat
Copy link

Bush-cat commented Oct 2, 2024

No available Light mode in Git Extensions has always bugged me, so I tried to fix it quickly by trying out this project
https://github.com/BlueMystical/Dark-Mode-Forms

app
commit

I didn't spend a lot of time on it but I got this far already, I just lazyily implemented it where it seemed right, I didn't examine the code very much.

Some text became invisible and the Colors and Icons look washed out but are fixed when using the high contrast theme but the high contrast theme destroys other things
app-hc
commit

Maybe when I have enough time I can fix all Issues and publish a fork or if we're lucky the devs implement it as this is more of a workaround.

@gerhardol
Copy link
Member

Maybe when I have enough time I can fix all Issues and publish a fork or if we're lucky the devs implement it as this is more of a workaround.

Coordinate with the changes in .NET9: dotnet/winforms#11857
A month or so before official.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests