Can't read from RSOP_RegistryPolicySetting WMI class in root\RSOP namespace - c#

The class is documented in
http://msdn.microsoft.com/en-us/library/aa375050%28VS.85%29.aspx
And from this page it seems it's not an abstract class:
http://msdn.microsoft.com/en-us/library/aa375084%28VS.85%29.aspx
But whenever I run the code below I get an "Invalid Class" exception in ManagementObjectSearcher.Get(). So, does this class exist or not?
ManagementScope scope;
ConnectionOptions options = new ConnectionOptions();
options.Username = tbUsername.Text;
options.Password = tbPassword.Password;
options.Authority = String.Format("ntlmdomain:{0}", tbDomain.Text);
scope = new ManagementScope(String.Format("\\\\{0}\\root\\RSOP", tbHost.Text), options);
scope.Connect();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, new ObjectQuery("SELECT * FROM RSOP_RegistryPolicySetting"));
foreach (ManagementObject queryObj in searcher.Get())
{
wmiResults.Text += String.Format("id={0}\n", queryObj["id"]);
wmiResults.Text += String.Format("precedence={0}\n", queryObj["precedence"]);
wmiResults.Text += String.Format("registryKey={0}\n", queryObj["registryKey"]);
wmiResults.Text += String.Format("valueType={0}\n", queryObj["valueType"]);
}
In the first link above, it lists as a requirement something called a "MOF": "Rsopcls.mof". Is this something I should have but have not? How do I obtain it? Is it necessary in the querying machine or the queried machine? Or both?
I do have two copies of this file:
C:\Windows>dir rsop*.mof /s
Volume in drive C has no label.
Volume Serial Number is 245C-A6EF
Directory of C:\Windows\System32\wbem
02/11/2006 05:22 100.388 rsop.mof
1 File(s) 100.388 bytes
Directory of C:\Windows\winsxs\x86_microsoft-windows-grouppolicy-base-mof_31bf3856ad364e35_6.0.6001.18000_none_f2c4356a12313758
19/01/2008 07:03 100.388 rsop.mof
1 File(s) 100.388 bytes
Total Files Listed:
2 File(s) 200.776 bytes
0 Dir(s) 6.625.456.128 bytes free

Duh. I was using the wrong namespace. It was root\RSOP\Computer.

Related

C# .Net6.0-How Can I change Windows page file size(Virtual Memory) by C#?

In Windows default settings, the pagefile size is set to Automatically manage paging file size for all drives.
This project is quite special. It is not maintained by operators. These computers are only provided for internal personnel to handle business or learn business processes. These computers have no fixed users, they are placed in public areas. When they have problems, the person on duty will reinstall the system using the fixed ghost file and execute the script to optimize the system with one click. These devices are old, and there are some thin terminals with 4G memory and 64G hard disk. Before long, new devices will replace them and have new management solutions. As a temporary transitional scheme before replacing the new scheme, I think providing a simple "optimization" program will be the simplest way to deal with it at present.
I want to change the page file size to 20% - 50% of the physical memory through C# .net-6.0 like (Test Computer's Physical memory is 32 GB)
I checked some information and it seems that wmic can meet my needs.
wmic COMPUTERSYSTEM set AutomaticManagedPagefile=false
wmic PAGEFILESET where name ="C:\\pagefile.sys" set InitialSize=1638,MaximumSize=4095
I tested these two lines of commands on Windows10 2019 LTSC, and they worked well.But when I use code to execute,I have some problems.Here is my code:
internal static void ExecuteCmd(string command)
{
try
{
Process process = new();
ProcessStartInfo startInfo = new()
{
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true,
FileName = "cmd.exe",
Arguments = "/c " + command,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
process.StartInfo = startInfo;
process.Start();
}
catch(Exception e)
{
LogHelper.Error(e.Message);
}
}
internal static void ChangeSystemPageFileSize()
{
string? TotalPhysicalMemory = "0";
string? InitialSize = "0";
string? MaximumSize = "0";
try
{
ManagementObjectSearcher Search = new ManagementObjectSearcher();
Search.Query = new ObjectQuery("Select * From Win32_ComputerSystem");
foreach (ManagementObject obj in Search.Get().Cast<ManagementObject>())
{
TotalPhysicalMemory = $"{Math.Round(Convert.ToDouble(obj["TotalPhysicalMemory"]) / (1024 * 1024))}";
if (!string.IsNullOrWhiteSpace(TotalPhysicalMemory))
{
break;
}
}
InitialSize = Math.Floor(int.Parse(TotalPhysicalMemory) * 0.2).ToString().Trim();
MaximumSize = Math.Floor(int.Parse(TotalPhysicalMemory) * 0.5).ToString().Trim();
CommandHelper.ExecuteCmd("wmic COMPUTERSYSTEM set AutomaticManagedPagefile=false");
CommandHelper.ExecuteCmd("wmic PAGEFILESET where name =\"C:\\\\pagefile.sys\" set InitialSize=" + InitialSize +",MaximumSize=" + MaximumSize);
}
catch (Exception e)
{
LogHelper.Error(e.Message);
}
I have obtained the correct physical memory size, but only the first command executed takes effect.When computer restart,I get windows settings like .
Thanks #ProgrammingLlama #user9938
I updated the page file size setting through WMI. There may be a little problem:
InitialSize = (UInt32)Math.Floor(TotalPhysicalMemory * 0.2);
MaximumSize = (UInt32)Math.Floor(TotalPhysicalMemory * 0.5);
ManagementObject ComputerSystem = new($#"ROOT\CIMV2:Win32_ComputerSystem.Name='{Environment.MachineName}'");
ComputerSystem["AutomaticManagedPagefile"] = false;
ComputerSystem.Put();
ManagementObject PageFileSetting = new($#"ROOT\CIMV2:Win32_PageFileSetting");
PageFileSetting.SetPropertyValue("Name", "C:\\PAGEFILE.SYS");
PageFileSetting.SetPropertyValue("InitialSize", InitialSize);
PageFileSetting.SetPropertyValue("MaximumSize", MaximumSize);
PageFileSetting["Name"] = "C:\\PAGEFILE.SYS";
PageFileSetting["InitialSize"] = InitialSize;
PageFileSetting["MaximumSize"] = MaximumSize;
PageFileSetting.Put();
Neither the SetPropertyValue method nor the Put method can update the value of InitialSize MaximumSize Name
Maybe someone can give me some advice?
The following shows how to use ManagementObject to change the settings for the Windows page file (on the OS partition).
Note: The code below has had limited testing. It's recommended to conduct your own testing to ensure that the code functions as desired. While the code seems to set the PageFile sizes for the OS drive, there may be alternative (more desirable) methods of setting these values. Additionally, prior to running the code below ensure that you Create a System Restore Point. Also, ensure that you've performed a backup of your computer.
According to Win32_ComputerSystem class:
TotalPhysicalMemory
Total size of physical memory. Be aware that, under some
circumstances, this property may not return an accurate value for the
physical memory. For example, it is not accurate if the BIOS is using
some of the physical memory. For an accurate value, use the Capacity
property in Win32_PhysicalMemory instead.
Download/install NuGet package: System.Management
Add Application Manifest File:
In VS menu, click Project
Select Add New Item...
Select Application Manifest File (name: app.manifest)
Click Add
Open Solution Explorer:
In VS menu, click View
Select Solution Explorer
Modify requestedExecutionLevel:
In Solution Explorer, right-click app.manifest and select Open
Change From:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
Change To:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
It appears that the data for PagingFiles can be modified by the following:
Add the following using directives
using System.Management;
using Microsoft.Win32;
using System.Diagnostics;
Code:
public UInt64 GetTotalMemoryInMB()
{
UInt64 totalPhysicalMemoryInBytes = 0;
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select Capacity from Win32_PhysicalMemory"))
{
foreach (ManagementObject obj in searcher.Get())
{
if (obj == null)
continue;
totalPhysicalMemoryInBytes += obj["Capacity"] is null ? 0 : Convert.ToUInt64(obj["Capacity"]);
}
}
return totalPhysicalMemoryInBytes / 1024 / 1024;
}
public string SetPageFileWmi(uint initialSizePercentage, uint maximumSizePercentage)
{
StringBuilder sb = new StringBuilder();
//get Windows folder
string? winDir = Environment.GetEnvironmentVariable("windir");
//get drive letter that OS is installed on
string winDriveLetter = winDir?.Substring(0, 2) is null ? String.Empty : winDir.Substring(0, 2); //ex: C:
//get total physical memory
UInt64 totalPhysicalMemory = GetTotalMemoryInMB();
sb.AppendLine($"Total Physical Memory: {totalPhysicalMemory}");
//calculate initial size
UInt32 initialSize = Convert.ToUInt32(Math.Floor(totalPhysicalMemory * (initialSizePercentage / 100.0))); //ex: 20% / 100.0 = 0.2
initialSize = initialSize < 16 ? 16 : initialSize; //initial size needs to be >= 16 MB
//calculate maximum size
UInt32 maximumSize = Convert.ToUInt32(Math.Floor(totalPhysicalMemory * (maximumSizePercentage / 100.0))); //ex: 50% / 100.0 = 0.5
using (ManagementObject obj = new ManagementObject($#"ROOT\CIMV2:Win32_ComputerSystem.Name='{Environment.MachineName}'"))
{
//set value
obj.SetPropertyValue("AutomaticManagedPagefile", false);
//commit
obj.Put(new PutOptions() { Type = PutType.UpdateOnly });
}
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select Name from Win32_PageFile"))
{
foreach (ManagementObject obj in searcher.Get())
{
string? pfName = obj["Name"]?.ToString();
Debug.WriteLine($"pfName: '{pfName}'");
//only get the page file for the OS drive
if (!String.IsNullOrEmpty(pfName) && pfName.ToLower().StartsWith(winDriveLetter.ToLower()))
{
sb.AppendLine($"Name: {pfName}");
sb.AppendLine($"InitialSize: {initialSize}");
sb.AppendLine($"MaximumSize: {maximumSize}");
sb.AppendLine("");
using (ManagementObject obj2 = new ManagementObject($#"ROOT\CIMV2:Win32_PageFileSetting.Name='{pfName}'"))
{
//set value
//obj2.SetPropertyValue("Name", pfName);
obj2.SetPropertyValue("InitialSize", initialSize);
obj2.SetPropertyValue("MaximumSize", maximumSize);
//commit
obj2.Put(new PutOptions() { Type = PutType.UpdateOrCreate });
}
}
}
}
return sb.ToString();
}
Usage
string result = SetPageFileWmi(20, 50);
According to Changing the Location of the Pagefile, the registry location is HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\.
Update:
Here's a method to reset to the default setting:
public static string SetPageFileDefaultWmi()
{
using (ManagementObject obj = new ManagementObject($#"ROOT\CIMV2:Win32_ComputerSystem.Name='{Environment.MachineName}'"))
{
obj.SetPropertyValue("AutomaticManagedPagefile", true);
obj.Put(new PutOptions() { Type = PutType.UpdateOnly });
}
return "Paging file set to default.";
}
Resources:
How to automatically set the minimum and maximum paging file size?
Put Options Class
PutOptions Type Property
PutType Enum
Introduction To Page Files
Changing the Location of the Pagefile
Ternary Operator
Additional Resources:
RegistryKey Class
RegistryKey.OpenBaseKey
RegistryKey.OpenSubKey
RegistryKey.GetValue
RegistryKey.SetValue

Use of Dismount method of the Win32_Volume

How can I dismount a logical drive temporarily on my computer in c#? I am looking for a code that gives me similar results
Dismount/Hide Drives
//Do some work
Mount / Show Drives
I had tried this code to renaming the drive letters, but cannot understand how to use the Dismount method
ManagementObjectSearcher searchDrives = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Volume WHERE label = 'Data'");
foreach (ManagementObject Drive in searchDrives.Get())
{
Drive.Get();
Drive["DriveLetter"] = "M:";
Drive.Put();
}
This is the Method provided by WMI
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/vdswmi/dismount-method-in-class-win32-volume
How should I use it, please?

Getting Current Reading of CIM_Tachometer in order to Get Fan Current Speed

I am working on a project which supposed to include computer's fans status. Most of the properties I need can be acquired from the Win32_Fan class. Sadly, I couldn't find a way to use this class for getting the current reading of the fan speed. In the Win32_Fan MSDN page it is mentioned in the "DesiredSpeed" property that the current speed is determined by a sensor named CIM_Tachometer:
DesiredSpeed
Data type: uint64
Access type: Read-only
Qualifiers: Units ("revolutions per minute")
Currently requested fan speed, defined in revolutions per minute, when
a variable speed fan is supported (VariableSpeed is TRUE). The current
speed is determined by a sensor (CIM_Tachometer) that is associated
with the fan using the CIM_AssociatedSensor relationship.
This property is inherited from CIM_Fan.
For more information about using uint64 values in scripts, see
Scripting in WMI.
After I saw that, I searched for this Tachometer CIM sensor and found the following code snippet (which was taken from http://wutils.com/wmi/root/cimv2/cim_tachometer/cs-samples.html):
//Project -> Add reference -> System.Management
//using System.Management;
//set the class name and namespace
string NamespacePath = "\\\\.\\ROOT\\cimv2";
string ClassName = "CIM_Tachometer";
//Create ManagementClass
ManagementClass oClass = new ManagementClass(NamespacePath + ":" + ClassName);
//Get all instances of the class and enumerate them
foreach (ManagementObject oObject in oClass.GetInstances())
{
//access a property of the Management object
Console.WriteLine("Accuracy : {0}", oObject["Accuracy"]);
}
And so I tried implementing it in my code:
public static String[] GetFanInfo()
{
ManagementClass cSpeed = new ManagementClass
("\\\\.\\ROOT\\cimv2:CIM_Tachometer"); //Create ManagementClass for the current speed property
ManagementObjectSearcher temp = new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSAcpi_ThermalZoneTemperature"); //Create management object searcher for the temperature property
ManagementObjectSearcher mos = new ManagementObjectSearcher
("SELECT * FROM Win32_Fan"); //Create a management object searcher for the other properties
string[] Id = new string[8]; //Preparig a string array in which the results will be returned
Id[0] = "Fan"; //First value is the category name
foreach (ManagementObject mo in mos.Get())
{
Id[1] = mo["Name"].ToString(); //Name of the component
Id[2] = mo["Status"].ToString(); //Component's status
long vel = Convert.ToInt64(mo["DesiredSpeed"]); //Desired speed of the component
Id[4] = Convert.ToString(vel);
bool s = Convert.ToBoolean(mo["variableSpeed"]); //Wheater or not variable speed are supported
Id[5] = s.ToString();
break;
}
foreach (ManagementObject obj in temp.Get())
{
Double temperature = Convert.ToDouble(obj["CurrentTemperature"].ToString()); //Fetching the temperature
Id[3] = Convert.ToString((temperature - 2732) / 10.0) + " C";
}
foreach (ManagementObject sObject in cSpeed.GetInstances()) //Get all instances of the class and enumerate them
{
Id[7] = sObject["CurrentReading"].ToString(); //Getting the current reading
}
return Id;
}
To my surprise, it seems that the whole section of the current reading is skipped during runtime. occur anyway!
My question is, why is this certain part skipped? Is the Tachometer a sensor which cannot be used? is it disabled for some reason?
Thanks ahead.
P.S.
I'm writing the program in Microsoft Visual Studio 2015 using winforms for the user interface.

Try to read Values in LOcal Group policy

I am trying to read two setting values in Local Group policy (gpedit.msc). The path is :
Local Computer Policy\Windows Settings\Security Settings\Local Policies\User Rights Assignment
The Policy that I want to read are :
1. Perform volume maintainace tasks (Users assigned to it)
2. Lock Pages in memory (Users assigned to it).
I have searched the web (including all stackoverflow threads) and could not find a solution to this but could not get a solution to this. Below is the code I am using currently but it only returns me 7 values.
I am not sure if this is possible. Please suggest. I am using C# .NET as language and would prefer if possible be able to read these setting from a remote machine (so I am preferring WMI approach).
Also I only want to read values. Now editing or writing...
Please suggest..
Girija
Code
private void Test()
{
ManagementScope scope =
new ManagementScope(
"\\\\localhost\\root\\rsop\\Computer");
scope.Connect();
ObjectQuery query = new ObjectQuery(
"SELECT * FROM RSOP_UserPrivilegeRight");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
List<string> val = new List<string>();
foreach (ManagementObject mgo in queryCollection)
{
var d = mgo["Name"];
val.Add(Convert.ToString(d));
}
}

different results for web and desktop applications for same code

I have the following piece of code.
It is returning different results when running on the same machine in case of web and desktop applications.
Here is my code. Please guide me on what to do regarding this???
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
return (from ManagementObject wmiHD in searcher.Get()
select wmiHD["SerialNumber"] == null ? "VM HD" : wmiHD["SerialNumber"].ToString()).ToList();
Here is a LINQ-free version of the same code
var hdCollection = new List<string>();
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
foreach (ManagementObject wmiHD in searcher.Get())
{
// get the hardware serial no.
if (wmiHD["SerialNumber"] == null)
{
hdCollection.Add("VM HD");
}
else
{
hdCollection.Add(wmiHD["SerialNumber"].ToString());
}
}
return hdCollection;
That could possibly be caused by two things:
web server runs with different user account (probably NetworkService)
http://www.bluevisionsoftware.com/WebSite/TipsAndTricksDetails.aspx?Name=AspNetAccount
web server runs code without Fulltrust permissions (probably medium trust)
http://discussion.accuwebhosting.com/iis-web-server/993-how-grant-full-trust-mode-domain-asp-net-2-0-iis-6-0-a.html
Both actions can compromise security, but the first one gives more choices to fix this by setting ACLs.

Categories

Resources