Abdelrhman-AK / WinPaletter

Advanced Windows Appearance Editor
Other
1.35k stars 54 forks source link

[Beta] The command line application changes the title bar. #225

Closed boromyr closed 5 months ago

boromyr commented 5 months ago

:x: Error report

Describe the error

Applying the WP theme from the command line, the title bar buttons are altered, switching from those of the currently applied msstyle theme to the default Windows ones, while applying the theme from the GUI this does not happen.

How to reproduce the error

Screenshots/Screen records

2

Additional context

Abdelrhman-AK commented 5 months ago

I made a step in code to reuse aero.msstyles (or the previous msstyles if aero is not applied before opening WinPaletter) if the default theme is chosen in Windows 11/10 colors. This should happen in both the GUI and command line, without any difference between both.

I'll try to reproduce this issue and fix it.

boromyr commented 5 months ago

I also noticed that when

  "Windows11": {
    "Enabled": false,

the problem does not occur. I don't know if you are familiar with https://github.com/namazso/SecureUxTheme, but it could be a great addition or solution for managing msstyle themes. It doesn't require modifications to system files, just registering a dll, and it could allow WP to directly manage themes, compatible with third-party themes as well.

Abdelrhman-AK commented 5 months ago

The actual cause of the issue is the Theme entry:

  "Windows11": {
    "Enabled": true,
    "Theme": 0,

- I can create another value for Theme to prevent WinPaletter from editing the current visual styles.

- If you have multiple users, the command prompt method may have an issue with retrieving the current user (since the command line attempts to apply the theme as silently as possible). I'll redo some tests.


I'm not sure if you're familiar with https://github.com/namazso/SecureUxTheme, but it could be a great addition or solution for managing msstyle themes. It doesn't require modifications to system files; you simply need to register a DLL, and it could allow WP to directly manage themes, compatible with third-party themes as well.

- I might quickly create an aspect that manages visual styles provided that UxTheme.dll is patched. If I succeed at this, I'll implement this feature. I'll do some tests. Didn't work.

Abdelrhman-AK commented 5 months ago

I have just found it.

FirstVisualStyles = UxTheme.GetCurrentVS().Item1 ?? SysPaths.Windows + "\\Resources\\Themes\\aero\\aero.msstyles";
boromyr commented 5 months ago

Should I compile the latest commit and test it? Yes, "Enabled": false was only used to isolate the issue and simplify the tests.

No need to patch any files, just register SecureUxTheme.dll, then you can apply the theme you want through the GUI or through the ThemeUI.dll library https://github.com/namazso/SecureUxTheme/issues/120, it is also used by Rectify11.

Abdelrhman-AK commented 5 months ago

Should I compile the latest commit and test it? Yes, "Enabled": false was only used to isolate the issue and simplify the tests.

Yes, you can compile and test it.

No need to patch any files, just register SecureUxTheme.dll, then you can apply the theme you want through the GUI or through the ThemeUI.dll library https://github.com/namazso/SecureUxTheme/issues/120, it is also used by Rectify11.

I'll try implementing it.

boromyr commented 5 months ago

I can no longer compile WP, I manually downloaded the missing NuGet packages: image but imageprocessor, even if installed, is not recognized, and devcorp cannot be found in the NuGet search. If you have the compiled file, can you upload it? Let's do it faster.

Abdelrhman-AK commented 5 months ago

https://github.com/Abdelrhman-AK/WinPaletter/blob/master/WinPaletter%2FResources%2FAssemblies.zip

Assemblies are zipped and added into apps's resources, and when an assembly is required, WinPaletter opens this zip into memory, loads it and finally closes the zip memory stream.

Download this ZIP, extract it and load missing assemblies and make them not copied into the local directory if you want.

Abdelrhman-AK commented 5 months ago

I was about to push a new update today, but I will wait for you to test it. Please redownload the latest project, I have just committed new changes.

boromyr commented 5 months ago

Where should I extract them exactly so that they are detected by VS? If you have WinPaletter.exe ready, I can try that directly.

Abdelrhman-AK commented 5 months ago

Anywhere you like, remove the missing assmebly then readd it from the directory into which you've extracted.

image

boromyr commented 5 months ago

Ok, filled out. I'll do some tests and let you know

boromyr commented 5 months ago

From the GUI I can apply the theme without any problem, through the CLI I get the error:

//General information
//...........................................................
   Report.Date = "martedì 26 marzo 2024 00:04:30";
   OS = "Windows 11, 10.0.22635.3350, 64-bit";
   WinPaletter.Version = "1.0.8.9, Beta, Build: Release";
   WinPaletter.Language = "English";
   WinPaletter.Debugging = false;

//Error details
//...........................................................
   Exception.message = "Object reference not set to an instance of an object.";
   Exception.type = "System.NullReferenceException";
   Exception.stack.trace =
   {
      at WinPaletter.Theme.Structures.Win32UI.Apply(TreeView treeView)
      at WinPaletter.Theme.Manager.<>c__DisplayClass0_1.<Save>b__24()
      at WinPaletter.Theme.Manager.Execute(MethodInvoker method, TreeView treeView, String statingStr, String errorStr, String TimeStr, Stopwatch overallStopwatch, Boolean skip, String skipStr)
   };
   Exception.target.void_function = "WinPaletter.Apply()";
   Exception.assembly = "WinPaletter, Version=1.0.8.9, Culture=neutral, PublicKeyToken=null";
   Exception.assembly.file = "C:\\Program Files\\WinPaletter.exe";
   Exception.HRESULT = -2147467261;
Abdelrhman-AK commented 5 months ago

In Solution explorer: WinPaletter > Theme > Structures > Windows Colors > Win32UI.cs

Line: 364

                    case WindowStyle.W11:
                        _vs = Program.TM.VisualStyles_11; <---------------------
                        break;

I'll work on it right now, and tell you what I did.

Abdelrhman-AK commented 5 months ago

In Solution explorer: WinPaletter > Program > Arguments.cs In private static void ExecuteArgs(string[] args = null, bool canExit = true)

if (o.Apply != null)
{
    if (System.IO.File.Exists(o.Apply))
    {
        using (Theme.Manager TMx = new(Theme.Manager.Source.File, o.Apply, false, o.SilentApply))
        {
            Forms.Home.Text = System.IO.Path.GetFileName(o.Apply);
            Program.TM = TMx.Clone() as Theme.Manager; // <------ new line
            TMx.Save(Theme.Manager.Source.Registry, string.Empty, null, false, o.SilentApply);
            if (Settings.ThemeApplyingBehavior.AutoRestartExplorer) RestartExplorer();

            ExternalLink = true;
            ExternalLink_File = o.Apply;
        }
    }

    shouldExit = true;
}

The new two lines fixed the issue

Abdelrhman-AK commented 5 months ago

This issue is new. It is relevant to Visual Styles new aspect.

boromyr commented 5 months ago

Ok, it works. I also tried enabling the msstyle theme with the new secureuxtheme integration and it didn't cause any issues. Now I will try uninstalling ultrauxtheme and see if the theme change works correctly with secureuxtheme.

How can I disable this window? image

Abdelrhman-AK commented 5 months ago

Is this the first time for this dialog to appear?

boromyr commented 5 months ago

It has always appeared to me since 1.0.8.4, or earlier...

Abdelrhman-AK commented 5 months ago

I made this appears everytime you open WinPaletter if there are multiple users. WinPaletter will work on the scope of the selected user. It cannot be currently disabled.

I can make a choice to automatically select the user who opened WinPaletter, if you want this.

boromyr commented 5 months ago

I have only one user on the computer, I don't know who the other one is.

I can make a choice to automatically select the user who opened WinPaletter, if you want this. Surely it would be more convenient, even for other users.

Abdelrhman-AK commented 5 months ago

It must be from a service that have installed by another program.

We will try to change its type from Local User to System Profile.

In command prompt, type NET USER and give me the output, or try instead NETPLWIZ.

boromyr commented 5 months ago

Maybe it depends on the disabled UAC?


Account utente per \\PC

-------------------------------------------------------------------------------
Administrator            DefaultAccount           Guest
PC                       WDAGUtilityAccount
Esecuzione comando riuscita.
Abdelrhman-AK commented 5 months ago

No. I have tested it without UAC. It is not the cause.

What about using netplwiz?

boromyr commented 5 months ago

image Maybe it could be a residual account from some test that you don't remember or from the online account? I will also search in the system registry, maybe I could find something.

Abdelrhman-AK commented 5 months ago

It is not residual, I have actually tested it dozens of times in my real PC and Virtual Machines when I implemented this feature.

I have noticed that this user account PC's name is NT Service and is different from your PC's name. I can make this account hidden among the system profiles in WinPaletter.

I'll provide you with codes updates when I finish.

boromyr commented 5 months ago

Ok thank you, here are the results if they can be helpful to you image

Abdelrhman-AK commented 5 months ago

Thanks for this screenshot, we won't manipulate this account.

I'll make it hidden.

Abdelrhman-AK commented 5 months ago

In Solution explorer: WinPaletter > Program > Users > Users.cs In public static Dictionary<string, string> GetUsers(bool includeSystemProfiles = false)

update it by

        public static Dictionary<string, string> GetUsers(bool includeSystemProfiles = false)
        {
            Dictionary<string, string> result = new();
            List<string> FoundSIDs = new();

            if (!OS.WXP)
            {
                try
                {
                    SelectQuery query = new("Win32_UserProfile");
                    ManagementObjectSearcher searcher = new(query);
                    ManagementObjectCollection managementObjects = searcher.Get();

                    foreach (ManagementObject SID in managementObjects.Cast<ManagementObject>()) { FoundSIDs.Add(SID["SID"].ToString()); }
                }
                catch
                {
                    foreach (string SID in GetSubKeys("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList")) { FoundSIDs.Add(SID); }
                }
            }
            else
            {
                foreach (string SID in GetSubKeys("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList")) { FoundSIDs.Add(SID); }
            }

            foreach (string sid in FoundSIDs)
            {
                try
                {
                    string username = new SecurityIdentifier(sid).Translate(typeof(NTAccount)).ToString();
                    bool condition_base = includeSystemProfiles | !(username.ToUpper().StartsWith("NT AUTHORITY", StringComparison.OrdinalIgnoreCase) && !username.ToUpper().StartsWith("NT SERVICE", StringComparison.OrdinalIgnoreCase));
                    bool condition_DAT_Loaded = includeSystemProfiles || (condition_base && RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Registry32).GetSubKeyNames().Contains(sid));
                    bool condition_DAT_Unloaded = !condition_DAT_Loaded && condition_base && System.IO.File.Exists($"{User.GetUserProfilePath(sid)}\\NTUSER.DAT");

                    if (condition_DAT_Unloaded)
                    {
                        Program.SendCommand($"reg load HKU\\{sid} \"{User.GetUserProfilePath(sid)}\\NTUSER.DAT\"");
                    }

                    if (condition_DAT_Loaded || condition_DAT_Unloaded)
                    {
                        result.Add(sid, username);
                    }

                }
                catch { } // Don't list a user that couldn't be got from SID using the registry in Windows XP
            }

            return result;
        }

I have done small changes. Update this void, test it and tell me.

boromyr commented 5 months ago

Unfortunately, nothing changes, maybe instead of using StartsWith() there is a method contains to check if "NT" is contained?

Abdelrhman-AK commented 5 months ago

If someone called his PC NT 012 for example, WinPaletter will deal with this user as a system user, not a regular one.

string username = new SecurityIdentifier(sid).Translate(typeof(NTAccount)).ToString();
MsgBox(username);

When the NT Service we want appers in the message box, press on Ctrl+C to copy message box content and paste it here.

boromyr commented 5 months ago

[Window Title] WinPaletter

[Main Instruction] NT SERVICE\lkClassAds

I have therefore tried without success.

bool condition_base = includeSystemProfiles | !(username.ToUpper().StartsWith("NT AUTHORITY", StringComparison.OrdinalIgnoreCase) && !username.ToUpper().StartsWith("NT SERVICE\\lkClassAds", StringComparison.OrdinalIgnoreCase));
Abdelrhman-AK commented 5 months ago

My bad !!!

bool condition_base = includeSystemProfiles | !(username.ToUpper().StartsWith("NT AUTHORITY", StringComparison.OrdinalIgnoreCase) || username.ToUpper().StartsWith("NT SERVICE", StringComparison.OrdinalIgnoreCase));
boromyr commented 5 months ago

ah see, it was an OR, I didn't notice it either, now it works!!!!

Abdelrhman-AK commented 5 months ago

Great! I'll post a new update tonight.

boromyr commented 5 months ago

Furthermore, the msstyle theme change also works without a patched uxtheme.

Abdelrhman-AK commented 5 months ago

How is this?

boromyr commented 5 months ago

Sorry, what do you mean? Maybe I expressed myself poorly, I meant that WP now correctly changes the msstyle theme with the new secureuxtheme integration. I uninstalled uxthemepatcher last night to avoid false positives, and to verify that WP was actually using SecureUxTheme, and it works fine.

Abdelrhman-AK commented 5 months ago

Great. I've understood you.