Shortcuts
There is no legal way to change the shortcut's (.lnk) tech properties except the well-known ones like TargetPath or Arguments.
The usual code for shortcut creation on C# is:
WshShell shell = new WshShell();
try
{
IWshShortcut link = (IWshShortcut)shell.CreateShortcut(myShortCutPath),
link.TargetPath = myExecutablePath,
link.Description = "Run my awesome app",
link.Arguments = myExecutableArgs,
link.Save(),
}
finally
{
Marshal.ReleaseComObject(shell);
}
This code will require adding COM dependency from Windows Script Host Object Model to your project.
But you can read about it in MSDN and StackOverflow.
What else we can do for the shortcut? With Windows Explorer UI we can set different compatiblity settings for our executable. But changing them does not changes the shortcut file. Moreover, if we change it for some shortcut, it changes for all of shortcuts for this executable. These settings are related to the exectuable itself and not to the shortcut.
What else we can do? We can create the Admin Shortcut. It will not apply on our executable, but will allow to run it from admin with this shortcut. There is no legal options to do this from code except byte hack. Binary comparison of two shortcuts with and without this checkbox on gives us the clue.
The 21th (0x15) byte from the beginning changes:
- the value of
0is default and means that checkbox is disabled - the value of
32(0x20) means that shortcut will run our executable from admin.
With knowing so we can use binary patching to alter this setting from code how we want.
0x20 is a single bit set in byte. What do the other ones mean? No answer. This is the weirdness of WinAPI.
Combatibility
SO gives us a clue of how we can change the executable's compatibility settings. All of them are stored in:
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
or (machine-wide, not only current user)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
There are a few values there with name of absolute executable's path, type of String and different values. Layers key may be missing,
so if we want to set up settings for some executable, we should create it.
Let's check them:
- Compatiblity with Windows 8 gives us
~ WIN8RTMvalue. - Compatiblity with Windows 7 gives us
~ WIN7RTMvalue. - Compatiblity with Windows Vista (Service Pack 2) gives us
~ VISTASP2value. - Compatiblity with Windows Vista (Service Pack 1) gives us
~ VISTASP1value. - Compatiblity with pure Windows Vista gives us
~ VISTARTMvalue. - Compatiblity with Windows XP SP3 gives us
~ WINXPSP3value. - Compatiblity with Windows XP SP2 gives us
~ WINXPSP2value. - Compatiblity with Windows 98/ME gives us
~ WIN98value. - Compatiblity with Windows 95 gives us
~ WIN95value.
Disabling the compatibility setting will remove the record from the registry.
Let's check the other checkboxes:
- 640x480 resolution gives us
~ 640X480value. - Disable display scaling gives us
~ HIGHDPIAWAREvalue. - Run from admin gives us
~ RUNASADMINvalue. - Run app from non-elevated user (not admin)
~ RUNASINVOKERvalue (update from 2 Jun 2021). - Reduced to 8-bit color gives us
~ 256COLORvalue. - Reduced to 16-bit color gives us
~ 16BITCOLORvalue.
Windows 10 Spring Update also added a few more settings:
- Fix scaling problems on sign in gives us
~ PERPROCESSSYSTEMDPIFORCEOFFvalue. - Fix scaling problems on open app gives us
~ PERPROCESSSYSTEMDPIFORCEONvalue. - Disable fullscreen optimizations gives us
~ DISABLEDXMAXIMIZEDWINDOWEDMODEvalue. - Override scaling with application gives us
~ HIGHDPIAWAREvalue (same as previous Disable display scaling). - Override scaling with system gives us
~ DPIUNAWAREvalue. - Override scaling with system (enhanced) gives us
~ GDIDPISCALING DPIUNAWAREvalue.
Combination of the flags gives as combined value like:
~ DISABLEDXMAXIMIZEDWINDOWEDMODE RUNASADMIN PERPROCESSSYSTEMDPIFORCEON HIGHDPIAWARE 640X480 16BITCOLOR WIN8RTM.
Don't know if order is meaningful, so here they are in order of Explorer created them. It seems, that tilda in the beginning is not critical, Explorer sets it, but it will work without it.
If you are really get confused with all of these flags - just open properties of the executable file and explore the Compatibility tab.
There are some another hacks (DWM8And16BitMitigation for example), they are related to DirectDraw and should be obtained from the appropriate documentation.
P.S. Complete list of compatibility flags can be obtained in MSDN.