Current I am able to get all the Drives and their labels in c# by using the DriveInfo.GetDrives(). Then I am able to get the Disk Index / Index of the Partition by this methodology.
var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskPartition");
foreach (var queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_DiskPartition instance");
Console.WriteLine("Name:{0}", (string)queryObj["Name"]);
Console.WriteLine("Index:{0}", (uint)queryObj["Index"]);
Console.WriteLine("DiskIndex:{0}", (uint)queryObj["DiskIndex"]);
Console.WriteLine("BootPartition:{0}", (bool)queryObj["BootPartition"]);
}
The problem with this is that the DiskIndex, Name, and Index are basically just numbers and not the Volume Label i.e. C:\, D:\, etc...
So bottom line how can I make the Volume Label which is the Name Proprty on the DriveInfo to the DiskIndex? Either using this methodology or a better way will work.
(This is a follow to: Tell if a Drive is a partition or a separate HDD)
EDIT:
I did find for the Management Query of the Win32_LogicalDisk and then the Win32_LogicalDiskToPartition. the LogicalDisk has the volume and the LogicalDisktoParition provides the mapping. However, I cannot seem to figure out how to get the map. I tried looking for a JOIN and selecting the values but couldn't find anything on how do this join without extensive looping in the c# code.
some time ago i had same problem and i do it with these code :
ListViewGroup hddgrp;
lstHDD.Columns.Add("Disk");
lstHDD.Columns.Add("Patition");
lstHDD.Columns.Add("Free Space");
lstHDD.Columns.Add("Total Space");
lstHDD.View = View.Details;
String DiskName = "";
String PartState = "";
String PartName = "";
String PartFree = "";
ManagementObjectSearcher hdd = new ManagementObjectSearcher("Select * from Win32_DiskDrive");
foreach (ManagementObject objhdd in hdd.Get())
{
PartState = "";
DiskName = "Disk " + objhdd["Index"].ToString() + " : " + objhdd["Caption"].ToString().Replace(" ATA Device", "") +
" (" + Math.Round( Convert.ToDouble(objhdd["Size"]) / 1073741824,1) + " GB)";
hddgrp = lstHDD.Groups.Add(DiskName, DiskName);
ObjCount = Convert.ToInt16(objhdd["Partitions"]);
ManagementObjectSearcher partitions = new ManagementObjectSearcher(
"Select * From Win32_DiskPartition Where DiskIndex='" + objhdd["Index"].ToString() + "'");
foreach(ManagementObject part in partitions.Get())
{
PartName = part["DeviceID"].ToString();
if (part["Bootable"].ToString() == "True" && part["BootPartition"].ToString() == "True")
PartState = "Recovery";
else
{
ManagementObjectSearcher getdisks = new ManagementObjectSearcher
("Select * From Win32_LogicalDiskToPartition Where ");
PartState = GetPartName(PartName);
PartFree = GetFreeSpace(PartState);
PartState = "Local Disk (" + PartState + ")";
}
lstHDD.Items.Add(new ListViewItem(new String[] { "Partition " + part["Index"].ToString(),
PartState,PartFree ,Math.Round( Convert.ToDouble(part["Size"].ToString()) / 1073741824,1) + " GB"}, hddgrp));
}
}
lstHDD.Columns[0].Width = 80;
lstHDD.Columns[1].Width = 120;
lstHDD.Columns[2].Width = 100;
lstHDD.Columns[3].Width = 100;
and two sub method :
private String GetFreeSpace(String inp)
{
String totalspace = "", freespace = "", freepercent = "";
Double sFree = 0, sTotal = 0, sEq = 0;
ManagementObjectSearcher getspace = new ManagementObjectSearcher("Select * from Win32_LogicalDisk Where DeviceID='" + inp +"'");
foreach (ManagementObject drive in getspace.Get())
{
if (drive["DeviceID"].ToString() == inp)
{
freespace = drive["FreeSpace"].ToString();
totalspace = drive["Size"].ToString();
sFree = Convert.ToDouble(freespace);
sTotal = Convert.ToDouble(totalspace);
sEq = sFree * 100 / sTotal;
freepercent = (Math.Round((sTotal - sFree) / 1073741824, 2)).ToString() + " (" + Math.Round(sEq,0).ToString() + " %)";
return freepercent;
}
}
return "";
}
private String GetPartName(String inp)
{
//MessageBox.Show(inp);
String Dependent = "", ret = "";
ManagementObjectSearcher LogicalDisk = new ManagementObjectSearcher("Select * from Win32_LogicalDiskToPartition");
foreach (ManagementObject drive in LogicalDisk.Get())
{
if (drive["Antecedent"].ToString().Contains(inp))
{
Dependent = drive["Dependent"].ToString();
ret = Dependent.Substring(Dependent.Length - 3, 2);
break;
}
}
return ret;
}
I hope this solution be useful.
for me this result is as below picture
You need to use the Win32_LogicalDisk class.
Edit: You are correct Win32_LogicalDiskToPartition. Is the link between Win32_LogicalDisk and Win32_DiskPartition. On Win32_LogicalDiskToPartition class, these two properties show the links,
PS> Get-WmiObject -Class Win32_LogicalDiskToPartition
Antecedent : \\computer\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1"
Dependent : \\computer\root\cimv2:Win32_LogicalDisk.DeviceID="D:"
Just parse these two properties and filter the the other classes appropriately.
Related
I am writing an app for doing changes to DNS resource records on local server.
I wrote a function to do it:
public void UpdateDomainRecord(string domainName, string recordname, IEnumerable<JProperty> content)
{
ResourceRecord Rezults = new ResourceRecord();
string wql = "";
wql += " SELECT * ";
wql += " FROM MicrosoftDNS_ResourceRecord";
wql += " WHERE OwnerName = '" + recordname + '.' + domainName + "'";
ObjectQuery q = new ObjectQuery(wql);
ManagementObjectSearcher s = new ManagementObjectSearcher(this.Session, q);
ManagementObjectCollection col = s.Get();
int total = col.Count;
foreach (ManagementObject o in col)
{
foreach (JProperty prop in content)
{
o.SetPropertyValue(prop.Name.ToString(),prop.Value.ToString());
}
o.Put();
}
}
It seems o.Put() method does not work: the loop changed the property of ManagementObject object but changes is not saved on server.
The app has all access it needs to connect to server.
I'm not trying to change properties that can not be changed.
Do you have any ideas on why it is not working?
I need to identify all drives and all logical partitions of each drive and I am having really troubles while dealing with memory cards (integrated reader in the laptop).
I am using this code
void GetFullInfoDiskDrives()
{
Global.LogMessage("************** GetFullInfoDiskDrives() Getting complete info from all disk drives ", 1);
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject info in searcher.Get())
{
// Lets print all the properties per disk
PropertyDataCollection properties = info.Properties;
// display the properties
Global.LogMessage("----------------- Properties for the disk " + info["Model"].ToString(),1);
foreach (PropertyData property in properties)
{
Global.LogMessage("[" + property.Name + "] = '" + property.Value +"'", 1);
foreach (QualifierData q in property.Qualifiers)
{
Global.LogMessage(" -" + q.Name + "- = '" + q.Value + "'", 1);
}
}
string s = "";
string s_model = info["Model"].ToString();
string s_interface = (info["InterfaceType"]==null? info["MediaType"].ToString():info["InterfaceType"].ToString());
string s_serialnumber = (info["SerialNumber"] == null ? "No serial number": info["SerialNumber"].ToString());
Global.LogMessage("Disk detected (Model: " + s_model + " | Interface: " + s_interface + " | Serial#: " + s_serialnumber,1);
foreach (ManagementObject o in info.GetRelated("Win32_DiskPartition"))
foreach (ManagementObject i in o.GetRelated("Win32_LogicalDisk"))
s += i["Name"] + " ";
Global.LogMessage("Logical disks: " + s,1);
}
}
The memory card doesn't seem to have a value for InterfaceType so I need to read MediaType instead. The same happens with the serial number, I don't know where to find it for a memory card.
Also, many values show its type (of value) in the value property such as
[Capabilities] = 'System.UInt16[]'
-CIMTYPE- = 'uint16'
How can I get the real value of this property?
I admit I am a bit lost and diving in the official documentation is not an easy task... :/
Could anybody put some light ?
Thanks!
Jose
After the good above suggestion from Rene, I tried to make it as dynamically as possible.
my goal is to cast the Property.value using the type from the value from the related QualifierData object.
My final working code is here. I am sure that there are more elegant ways to achieve it but this is the one I found. ;)
foreach (PropertyData property in properties){
foreach (QualifierData q in property.Qualifiers){
if (property.IsArray){
if (property.Value != null){
Type t = property.Value.GetType();
object o = property.Value;
dynamic foo = o;
if (IsPropertyExist(foo, "Length")){
string s1 = "";
for (int i = 0; i < foo.Length; i++)
s1 += "[" +foo[i] +"]";
Global.LogMessage("[" + property.Name + "] (" + q.Value + ") = " + s1 , 1);
}
This is my code, and i am getting problem with mos.Query and Get().Even after adding System.Management Namespace.
string processName = Process.GetCurrentProcess().MainModule.ModuleName;
ManagementObjectSearcher mos = new ManagementObjectSearcher();
mos.Query.QueryString = #"SELECT * FROM Win32_Process WHERE Name = '" + processName + #"'";
if (mos.Get().Count > 1)
{
return true;
}
else
{
return false;
}
When I restructure your code, I only ever receive one result, so your code would always return false, unless you have multiple instances of the same app with the same image name running.
var processName = Process.GetCurrentProcess().MainModule.ModuleName;
var mos = new ManagementObjectSearcher();
mos.Query.QueryString = #"SELECT * FROM Win32_Process WHERE Name = '" + processName + #"'";
var collection = mos.Get();
var count = collection.Count;
// If count == 1, the process is already running. If it's 0, it's not running. If it's > 1, then multiple copies are running.
return count == 1;
You may also want to do some reading on Mutex and Single Instance applications. There are many good tutorials here and elsewhere on the subject.
I programmed a project to manage Dns. I could code for create and delete Zone, NsRecord and ARecord, but I can't get ARecords of the Zone.
Can anyone guide me?
This is sample of my code:
private void CreateZone(string domainName)
{
wmiScope = new ManagementScope("\\\\" + System.Environment.MachineName + "\\ROOT\\MicrosoftDNs");
wmiScope.Connect();
var zonePath = new ManagementPath("MicrosoftDNs_Zone");
var zone = new ManagementClass(wmiScope, zonePath, null);
var inParams = zone.GetMethodParameters("CreateZone");
inParams.Properties["ZoneName"].Value = domainName;
inParams.Properties["ZoneType"].Value = 0;
zone.InvokeMethod("CreateZone", inParams, null);
var query = new ObjectQuery("SELECT * FROM MicrosoftDNs_SOAType WHERE OwnerName = '" + domainName + "'");
var searcher = new ManagementObjectSearcher(wmiScope, query);
var zoneRecordes = searcher.Get();
foreach (ManagementObject zoneRecorde in zoneRecordes)
{
var soaParams = zoneRecorde.GetMethodParameters("Modify");
soaParams.Properties["PrimaryServer"].Value = "ns1.domain.com";
soaParams.Properties["ResponsibleParty"].Value = "contact#domain.com";
zoneRecorde.InvokeMethod("Modify", soaParams, null);
}
}
To be complete I'll add the answer that got us to the solution.
According to the following site (discuss.fogcreek.com/dotnetquestions/…) you should be able to get the ARecords like this:
ManagementScope oMs = new ManagementScope("\\\\" + dnsServer + "\\root\\microsoftdns");
string strQuery = "select * from microsoftdns_" + recType + "type where containername = '" + domain + "'";
ManagementObjectSearcher oS = new ManagementObjectSearcher(strQuery); oS.Scope = oMs;
ManagementObjectCollection oRc = oS.Get();
I have a project where I have to handle sensitive data.
How do I open a keepass database from C# to use the data?
I have downloaded the source. I will look in it to get what I need. Any other idea?
I thought about reading a KeyPass 2 database so I added a reference to KeyPass.exe in Linqpad and started to experiment. To my surprise and without any outside help (a testament to a good API), I was reading the database after only a few minutes. Here's how I did it:
var dbpath = #"C:\path\to\passwords.kdbx";
var masterpw = "Your$uper$tr0ngMst3rP#ssw0rd";
var ioConnInfo = new IOConnectionInfo { Path = dbpath };
var compKey = new CompositeKey();
compKey.AddUserKey(new KcpPassword(masterpw));
var db = new KeePassLib.PwDatabase();
db.Open(ioConnInfo, compKey, null);
var kpdata = from entry in db.RootGroup.GetEntries(true)
select new
{
Group = entry.ParentGroup.Name,
Title = entry.Strings.ReadSafe("Title"),
Username = entry.Strings.ReadSafe("UserName"),
Password = entry.Strings.ReadSafe("Password"),
URL = entry.Strings.ReadSafe("URL"),
Notes = entry.Strings.ReadSafe("Notes")
};
kpdata.Dump(); // this is how Linqpad outputs stuff
db.Close();
Here is an extension of the original answer from Ronnie - walking the keepass tree recursively. This outputs a format that jsTree can use by the way.
public static void JsonData() {
var dbpath = Web.MapPath(#"your-password-file.kdbx");
var masterpw = "Your$uper$tr0ngMst3rP#ssw0rd";
var ioConnInfo = new IOConnectionInfo { Path = dbpath };
var compKey = new CompositeKey();
compKey.AddUserKey(new KcpPassword(masterpw));
var db = new KeePassLib.PwDatabase();
db.Open(ioConnInfo, compKey, null);
//get everything
var kpdata = from entry in db.RootGroup.GetEntries(true)
select new {
Group = entry.ParentGroup.Name,
Title = entry.Strings.ReadSafe("Title"),
Username = entry.Strings.ReadSafe("UserName"),
Password = entry.Strings.ReadSafe("Password"),
URL = entry.Strings.ReadSafe("URL"),
Notes = entry.Strings.ReadSafe("Notes")
};
var kproot = db.RootGroup.Groups;
string lastGroup = "#";
uint sc = 0;
int depth = 0;
var parent = "#"; //root is # parent
foreach (var entry in kproot) {
PwGroup pwGroup = db.RootGroup.Groups.GetAt(sc);
Web.Write(" { \"id\" : \"" + (sc) + "\", \"parent\" : \"" + parent + "\", \"text\" : \"" + pwGroup.Name.HtmlEncode() + "\" },\n");
WriteChildren(pwGroup,sc+"", depth + 1);
sc++;
}
db.Close();
}
public static void WriteChildren(PwGroup pwGroup, string parentID,int depth) {
uint sc = 0;
//if(depth>3)return; //used to prevent too much recursion
foreach (var entry in pwGroup.Groups) {
var subGroup = pwGroup.Groups.GetAt(sc);
var curID = (parentID+"_"+sc);
Web.Write(" { \"id\" : \"" + curID + "\", \"parent\" : \"" + parentID + "\", \"text\" : \"" + subGroup.Name.JsEncode() + "\"},\n");
WriteChildren(subGroup, curID, depth+1);
WriteLeaves(subGroup, curID, depth);
sc++;
}
}
public static void WriteLeaves(PwGroup pwGroup, string parentID,int depth) {
uint sc = 0;
//if(depth>3)return;
var entryList = pwGroup.GetEntries(false);
foreach (var entry in entryList) {
var curID = (parentID+"_"+sc);
Web.Write(" { \"id\" : \"" + curID + "\", \"parent\" : \"" + parentID + "\", \"text\" : \"" + entry.Strings.ReadSafe("Title").JsEncode() + "\", \"password\" : \"" + entry.Strings.ReadSafe("Password").JsEncode() + "\", \"type\" : \"file\"},\n");
sc++;
}
}
Check : KeePass Password Safe (For how keepass works)
Rather use the C# System.Cryptography classes and store you data enrypted in a database or txt file...
There is a KeePass-2.05-Alpha-Source.zip,The latest version of KeePass. C# source code,1919KB
http://s.pudn.com/upload_log_en.asp?e=1781366
http://en.pudn.com/downloads175/sourcecode/windows/other/detail816102_en.html