Adjust the screen brightness in a Windows 8 App - c#

I am developing a Windows 8 application. Is there a way I can access the device's brightness settings so the user can adjust the brightness of the device from inside the app? Thanks

I was using a batch file to change things but it also looks like Windows provided an API you can directly from C# (well p/Invoke and then call) as well... so all the above is still true and will still work, but you can also call
PowerGetActiveScheme
PowerWriteACValueIndex
PowerWriteDCValueIndex
Those links are nice too, because they have all the Sub guids listed out for you. So just P/Invoke those bad boys and call them directly from your app, no batch file needed :)

The built in windows Utility PowerCfg can change the brightness on the fly...
Typically PowerCfg is called from the cmd line or in batch files, but you can also call it from your app using Process.Start.
When using PowerCfg you needs to know several things:
The scheme guid: which is the guid associated with the power scheme you want to change.
The Sub Guid: Which is the guid associated with the power setting group you want to change.
The Setting Guid: Which is the guid associated with the actual setting in that power settings group you want to change.
The range or index value: Finally you need to know what value you want to change that setting to... Some settings have a range that you can set it to anything inside of that range, some settings have a list of values to choose and you need to know the index of the value you want.
The Scheme guid is actually the hardest one to get, since the user may have defined new schemes, and thus the guid needs to be found by calling PowerCfg -getactivescheme
The other guids are all constants and can be found by running PowerCfg - query
Once you have all the guids lined up you can set the ac (power plugged in) and dc (on battery) value for each setting. with:
POWERCFG -SETACVALUEINDEX <SCHEME_GUID> <SUB_GUID> <SETTING_GUID> <SettingIndex>
and
POWERCFG -SETDCVALUEINDEX <SCHEME_GUID> <SUB_GUID> <SETTING_GUID> <SettingIndex>
As an example... here is a little batch file that I use to turn off the Adaptive Brightness feature:
Echo Disable Adaptive Display Brightness Setting
for /f "tokens=2 delims=:" %%G in ('powercfg -getactivescheme') do set guid=%%G
for /f %%G in ("%guid%") do set guid=%%G
powercfg -setacvalueindex %guid% 7516b95f-f776-4464-8c53-06167f40cc99 fbd9aa66-9553-4097-ba44-ed6e9d65eab8 000
powercfg -setdcvalueindex %guid% 7516b95f-f776-4464-8c53-06167f40cc99 fbd9aa66-9553-4097-ba44-ed6e9d65eab8 000
The first couple of lines are getting the scheme guid, then the next two are setting the actual values
You could do something very similar for the Display Brightness settings... Which is this sub group and setting guid (same sub group as the Adaptive Brightness):
Subgroup GUID: 7516b95f-f776-4464-8c53-06167f40cc99 (Display)
Power Setting GUID: aded5e82-b909-4619-9949-f5d71dac0bcb (Display brightness)
Minimum Possible Setting: 0x00000000
Maximum Possible Setting: 0x00000064
Possible Settings increment: 0x00000001
Possible Settings units: %
To call it from your C# app you could build a cmd file on the fly and run it with Process.Start
Hope that helps!

Related

How to change language of powershell script? [duplicate]

I wrote some software that uses the output of system (powershell) commands, but did not foresee that the output would be different for languages other than English.
Is there a way to temporarily change the language in Powershell to English for just that one, single powershell session?
Notes
In case it is of significance, the particular powershell code I wish to run is netstat -n -a
I have come across some ways to change powershell language (e.g. here, here). But I want to be careful not to change it permanently! (that would be bad)
(a) For external programs such as netstat.exe, there is unfortunately no way (that I know of) to change the UI language in-session:
On Windows Server 2012 / Windows 8 and above, the Set-WinUILanguageOverride cmdlet allows you to (persistently) change the system-wide UI language for the current user, but that only takes effect in future logon sessions - that is, logging off and back on or a reboot are required.
As an aside: On Windows Server 2012 / Windows 8 and above, there is also the Set-Culture cmdlet, but its purpose is not to change the UI culture (display language), but only culture-specific settings such as date, number, and currency formats. It too changes the setting persistently for the current user, but only requires a new session (process) for the change to take effect.
(b) For PowerShell commands and .NET types, there is an in-session (non-persistent) solution - assuming the commands are culture-aware and come with localized strings:
Set [cultureinfo]::CurrentUICulture (temporarily) to the desired culture name (use [cultureinfo]::GetCultures('SpecificCultures') to see all predefined ones) ; e.g., [cultureinfo]::CurrentUICulture = 'en-US'
Complementarily, you may want to set [cultureinfo]::CurrentCulture (note the missing UI part) as well, which determines the culture-specific number, date, ... formatting.
In older versions of PowerShell / .NET, you'll have to set these properties on [System.Threading.Thread]::CurrentThread instead; e.g.,
[System.Threading.Thread]::CurrentThread.CurrentUICulture = 'en-US'
See the bottom section for helper function Use-Culture that wraps this functionality for execution of code with a different culture temporarily in effect; here's an example call
with the culture-sensitive Get-LocalGroupMember cmdlet:
# Try with values other than "en-US", e.g. "fr-FR" to see localized
# values in the "ObjectClass" output column.
Use-Culture en-US { Get-LocalGroupMember Administrators }
An ad hoc example, if you don't want to define a helper function (only the UI culture is changed here):
& {
$prev=[cultureinfo]::CurrentUICulture
[cultureinfo]::CurrentUICulture='en-US'
Get-LocalGroupMember Administrators
[cultureinfo]::CurrentUICulture=$prev
}
Caveats:
PowerShell [Core] itself is not localized yet, as of v7.2.x; progress is being tracked in GitHub issue #666; however, the solution below does work with third-party modules that ship with localized messages and help content, as well as select Windows-specific modules that talk to platform APIs, such as the Microsoft.PowerShell.LocalAccounts module, whose Get-LocalGroupMember cmdlet was used in the example above.
Due to a bug in Windows PowerShell (PowerShell [Core] v6+ is not affected), in-session changes to [cultureinfo]::CurrentUICulture and [cultureinfo]::CurrentCulture are automatically reset at the command prompt, whenever a command finishes executing; however, for a given script the changes remain in effect for the entire script and its callees - see this answer.
Taking a step back:
I wrote some software that uses the output of system (powershell) commands, but did not foresee that the output would be different for languages other than English.
This is precisely why it's generally worth looking for PowerShell-native solutions as opposed to calling external programs:
Instead of having to parse - possibly localized - text, as with netstat.exe, for instance, PowerShell commands return objects whose properties you can robustly access in a culture-independent fashion.
Specifically, Mathias R. Jessen suggests looking at Get-NetTCPConnection as a PowerShell alternative to netstat.exe (available on Windows Server 2012 / Windows 8 and above).
Function Use-Culture's source code:
Note: The code was gratefully adapted from this venerable blog post; it is designed
# Runs a script block in the context of the specified culture, without changing
# the session's culture persistently.
# Handy for quickly testing the behavior of a command in the context of a different culture.
# Example:
# Use-Culture fr-FR { Get-Date }
function Use-Culture
{
param(
[Parameter(Mandatory)] [cultureinfo] $Culture,
[Parameter(Mandatory)] [scriptblock] $ScriptBlock
)
# Note: In Windows 10, a culture-info object can be created from *any* string.
# However, an identifier that does't refer to a *predefined* culture is
# reflected in .LCID containing 4096 (0x1000)
if ($Culture.LCID -eq 4096) { Throw "Unrecognized culture: $($Culture.DisplayName)" }
# Save the current culture / UI culture values.
$PrevCultures = [Threading.Thread]::CurrentThread.CurrentCulture, [Threading.Thread]::CurrentThread.CurrentUICulture
try {
# (Temporarily) set the culture and UI culture for the current thread.
[Threading.Thread]::CurrentThread.CurrentCulture = [Threading.Thread]::CurrentThread.CurrentUICulture = $Culture
# Now invoke the given code.
& $ScriptBlock
}
finally {
# Restore the previous culture / UI culture values.
[Threading.Thread]::CurrentThread.CurrentCulture = $PrevCultures[0]
[Threading.Thread]::CurrentThread.CurrentUICulture = $PrevCultures[1]
}
}
Original author of this code is #Scepticalist.
Run this from powershell console. It will change the culture to en-US for current session.
function Set-CultureWin([System.Globalization.CultureInfo] $culture) { [System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture ; [System.Threading.Thread]::CurrentThread.CurrentCulture = $culture } ; Set-CultureWin en-US ; [system.threading.thread]::currentthread.currentculture
Then you have to use the command Get-NetTCPConnection Instead of netstat. For its usage see https://learn.microsoft.com/en-us/powershell/module/nettcpip/get-nettcpconnection?view=win10-ps

Windows Environment Variable Expansion: Admin vs Non-Admin

I have a C# application that when run sets some environment variables.
These environment variables need to be set system wide.
I use this code to actually do the set.
public static void SetEnvironmentVariable(string _keyName, string _value, RegistryValueKind _type)
{
using (RegistryKey reg = Registry.LocalMachine.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", true))
{
if (reg != null)
{
reg.SetValue(_keyName, _value, _type);
}
else
{
string x =
string.Format(
"Could find registry key that hosts Environment Variables: SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment");
App.AppLogger.Error(x);
throw new Exception(x);
}
}
}
This code works, but I notice some strange behavior.
Immediately after running my app and this code, I run cmd as a regular user and take a look a the environment using the "set" command.
It shows no changes.
I then run a cmd prompt as admin and run set. It shows the changes. Not only that, it shows fully expanded variables. Where ALLFOO=Foo, and PATH=C:\Windows\System32;%ALLFOO%;, the set command shows PATH=C:\Windows\System32;Foo;.
I then log off and back on. I then run cmd as a normal user.
I type set and it shows the new environment variables, but not expanded.
It shows PATH=C:\Windows\System32;%ALLFOO%; ( It seems to have no trouble expanding %SYSTEMROOT% for some reason.)
I get that the log-off and back on causes the new Explorer.exe that's launched to get the new env vars for the regular user's cmd.exe, but I don't understand why they are not expanded.
Why would running cmd and set as administrator show fully expanded environment variables and running cmd and set as a normal user would not?
When setting the env vars in the C# program i use the RegistryValueKind.ExpandString enumeration.
Edit:
I am aware of the order of declaration time to expansion time issue with system variables and have edited the question example to reflect this.
Changes to the environment variables are not inmediatly visible. You need to notify the running processes of changes to the registry.
And, you should remember that the environment you see in a process (your cmd windows) is not readed from the registry, it is inherited from its parent process. You can send the notification, but some processes will handle it and some not.
The rest of the problems should be explained by the environment load order:
Some values are retrieved from the registry before processing the environment itself. %systemroot% is defined in
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRoot
System environment is loaded
REG_SZ variables, in alphabetic order, are readed first
REG_EXPAND_SZ, in alphabetic order, are readed. As the REG_SZ values have been readed, they can be expanded. If a REG_EXPAND_SZ variable makes reference to another REG_EXPAND_SZ variable that still has not been expanded (alphabetic order), this reference can not be resolved and is not expanded.
When the user logs in, the user environment is processed.
Same REG_SZ, then REG_EXPAND_SZ variable are processed.
Variables defined at user level overwrite the values of the system environment, except for some variables (ex. PATH) where the values are concatenated.
All that means that
Different users can and probably will see different environments
Same user can see different environments depending on what the parent process is. It is not the same to use Win+R and execute cmd than to use Shift+right click in a folder and select "Open command here". Parent processes are different.

Checking Elasticsearch Heap Size

How can I check the heap size that is assigned to Elasticsearch engine, is there a way to check it using URL API ? And can I use NEST to check it?
Thanks
In a clustered environment, heap settings can be queried as :
curl -sS "localhost:9200/_cat/nodes?h=heap*&v"
Eg:
curl -sS "localhost:9200/_cat/nodes?h=heap*&v"
heap.current heap.percent heap.max
321.1mb 32 989.8mb
424.1mb 42 989.8mb
280.3mb 28 989.8mb
This can also be checked from the ps results, though it will only shed light on the min-max values.
~#ps aux | grep --color=auto -i Xms
elastic 6020 0.0 0.0 12788 936 pts/4 S+ 04:24 0:00 grep --color=auto -i Xms elastic+ 7218
0.6 9.5 5001220 1565112 ? Ssl Jun24 5:14 /usr/bin/java -Xms1g -Xmx1g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.io.tmpdir=/tmp/elasticsearch.WoiU4NhH -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch -XX:ErrorFile=/var/log/elasticsearch/hs_err_pid%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -Xloggc:/var/log/elasticsearch/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=32 -XX:GCLogFileSize=64m -Xms1g -Xmx1g -Des.path.home=/usr/share/elasticsearch -Des.path.conf=/etc/elasticsearch -Des.distribution.flavor=default -Des.distribution.type=deb -cp /usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch -p /var/run/elasticsearch/elasticsearch.pid --quiet
where -Xms is the minheap and -Xmx is maxheap configured.
use GET _nodes/stats
Then look at the following in the return /jvm/mem/heap_committed_in_bytes
This is a new account so I couldn't comment on jhilden's answer. His answer is correct but to answer your comment I use Postman which is a chrome app. It's very easy to use and has been ideal for me whilst working with Elasticsearch.
Putting the following in postman and hitting send does the job!
http://localhost:9200/_nodes/stats
review the results and look for the "jvm" block. Here is what is returned when I run it on a default elasticsearch setup:
"jvm": {
"timestamp": 1477474766408,
"uptime_in_millis": 1309586,
"mem": {
**"heap_used_in_bytes": 87134248**,
"heap_used_percent": 8,
"heap_committed_in_bytes": 259522560,
"heap_max_in_bytes": 1038876672,
"non_heap_used_in_bytes": 56166992,
"non_heap_committed_in_bytes": 57348096,
As per the online documentation, the default heap size is 1 Gb unless you explicitly mention in the Environment Variable [ES_HEAP_SIZE]
The default installation of Elasticsearch is configured with a 1 GB
heap. For just about every deployment, this number is far too small.
If you are using the default heap values, your cluster is probably
configured incorrectly.
There are two ways to change the heap size in Elasticsearch. The
easiest is to set an environment variable called ES_HEAP_SIZE. When
the server process starts, it will read this environment variable and
set the heap accordingly. As an example, you can set it via the
command line as follows:
export ES_HEAP_SIZE=10g Alternatively, you can pass in the heap size
via a command-line argument when starting the process, if that is
easier for your setup:
./bin/elasticsearch -Xmx10g -Xms10g
Ensure that the min (Xms) and max (Xmx) sizes are the same to prevent
the heap from resizing at runtime, a very costly process.
Generally, setting the ES_HEAP_SIZE environment variable is preferred
over setting explicit -Xmx and -Xms values.

C# change windows UAC level to Always Notify

I want to change the UAC level of the machine to "Always Notify" level which is the top level.
I tried changing the following registry key value to 1.
Key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
const string UACkey = #"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
const string Subkey = "EnableLUA";
RegistryUtilities.SetValue(UACkey, Subkey, **1**, Microsoft.Win32.RegistryValueKind.DWord, RegistryUtilities.WOW64Key.Key64);
This result in UAC to be in 3rd level (Notify when programms try to make changes).
How to set it to top level?
I managed to find this by changing UAC and having regedit open at the same time, and watching which values changed.
When on the top setting, the value
ConsentPromptBehaviorAdmin
changes to 2, rather than 5 when it's on the 3rd level (nice logic there Microsoft). Changing that value as well as EnableLUA should do it.
Hope this helps

API to toggle "Show hidden files, folders and drives"

Is there a function in Windows API to toggle the "Show hidden files, folders and drives" option in Windows Explorer (Tools >> Folder Options... >> View tab).
I know of a related registry key, but changing that would not have immediate effect. The key is: HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Explorer/Advanced/Hidden
Trying to do this from C#, but the question is not language-specific.
You could try the options the OP in this thread suggests, that is:
Either
SendNotifyMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);
or
RefreshPolicyEx(False, RP_FORCE);
or
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, integer(pchar('Policy')), SMTO_NORMAL or SMTO_ABORTIFHUNG, 5000, c1);
These are not in the .NET C# API, so you'll have to use DllImport
Edit: formatting
In addition to the comment I've added to the original question - if you're doing this so that, for instance, the OpenFileDialog you're about to pop open shows these files - don't do it.
In that case, you're better P/Invoking GetOpenFileName, and setting the appropriate option (OFN_FORCESHOWHIDDEN (see enum for a related subject) in the flags of the OpenFileName structure.
That way you're only affecting your application, at the appropriate time
I know of no API, but the registry key is HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Hidden. From experimentation, it seems a value of 1 means show and a value of 2 means hide.
SHGetSetSettings
SHELLSTATE Structure
fShowAllObjects
BOOL
TRUE to show all objects, including hidden files and folders. FALSE to hide hidden files and folders.
fShowSysFiles
BOOL
TRUE to show system files, FALSE to hide them.
Spy++ says a WM_SETTINGCHANGE is sent to the explorer windows.

Categories

Resources