How to display a registry key(s) in a text box C# - c#

I am having trouble displaying all the registry keys in the startup section for Windows. I want to display all of the registry keys that tell programs to startup in a text box. I have been able to create a directory listing for the HKEY_LOCAL_MACHINE, but I can't manage to narrow it down to the keys listed in the HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run directory. Here is my code:
TreeNode localMachineNode = new TreeNode(Registry.LocalMachine.Name);
string[] localMachineSubKeys = Registry.LocalMachine.GetSubKeyNames();
foreach (string key in localMachineSubKeys)
{
TreeNode node = new TreeNode(key, 0, 1);
}
If there is a better way to do this, i'd love to hear about it. Mind you, that is only part of my code.

Use OpenSubKey to open a key using a path:
var runs = Registry.LocalMachine.OpenSubKey(
#"Software\Microsoft\Windows\CurrentVersion\Run");
var valueNames = runs.GetValueNames();
var values = new List<object>();
foreach (var valueName in valueNames)
{
values.Add(runs.GetValue(valueName));
}

Is this what you are after?
var keys = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Run")
.GetSubKeyNames();

Related

Windows, C#: reading eventlog entries from active AND saved logs

I know that I can read the Security logs of a Windows PC using:
var securityLog = new EventLog("security");
foreach (EventLogEntry entry in securityLog.Entries) {
...
}
The entry item contains all the interesting log fields I expect to see like: InstanceId, Message and others. What I want to do now is read the same things from an event log that was saved to disk as an .evtx file.
I have seen suggestions for using
string xpathQuery = "*";
var eventsQuery = args.Length == 0
? new EventLogQuery("Security", PathType.LogName, xpathQuery)
: new EventLogQuery(args[0], PathType.FilePath, xpathQuery);
using (var eventLogReader = new EventLogReader(eventsQuery)) {
EventLogRecord entry;
while ((entry = (EventLogRecord) eventLogReader.ReadEvent()) != null) {
...
}
}
but the entry in the second version doesn't contain the same members/values as the first example. I totally dig that I am confused and am looking at the problem the wrong way.
How should one go about reading the actual per record content from either an active or saved system log?
Or, can I go from an EventLogRecord to an EventLogEntry? I have not seen that conversion method yet.

Registry read permissions

I want to list out all user data sources using c# but I can't do it because I don't have permission to read the registry key. How can I get all user data sources?
I tried below code but no use
private List<string> ENUMDSN()
{
List<string> list = new List<string>();
list.AddRange(ENUMDSN(Registry.CurrentUser));
list.AddRange(ENUMDSN(Registry.LocalMachine));
XElement xmlele = new XElement("list", list.Select(i => new XElement("list", i)));
return list;
}
private IEnumerable<string> ENUMDSN(RegistryKey rootkey)
{
RegistryKey regkey = rootkey.OpenSubKey(#"Software\ODBC\ODBC.INI\ODBC Data Sources");
foreach (string name in regkey.GetValueNames())
{
string value = regkey.GetValue(name, "").ToString();
yield return name;
}
}
"CurrentUser" registry keys doesn't need any specific permission you can read/write without any problem, but if you want to read keys which in the "LocalMachine" subkey you have to have administrator permissions, there is no other way.
EDIT:
If you run your code under IIS you cannot get key values under the "CurrentUser" or "LocalMachine" because IIS Application Pools doesn't run under your "current account" they runs under their "user accounts".
For solution maybe you can change your Application Pool's user account but it's not recommended for some security reasons.

C# gpresult /r equivalent

I'm writing a small app that checks to see if a computer and current user are members of the appropriate security groups in Active Directory. I stumbled across this question LINK but it looks like it was forgotten and I'm running into the same issues as the OP. The end result is I want to be able to create an array that is very similar to running the following command from a command prompt.
gpresult /r
Here is a code sample that I have tried from the above link, I'm running into the same errors as the OP specifically "out of range" exception" when attempting to set LoggingUser and LoggingComputer. Since I can't get past these errors I'm not even sure if this method is the right route.
GPRsop rsop = new GPRsop(RsopMode.Logging, "root\\RSOP\\Computer");
rsop.LoggingComputer = "MyComputer";
rsop.LoggingUser = "domain\\user";
rsop.LoggingMode = LoggingMode.Computer;
rsop.CreateQueryResults();
rsop.GenerateReportToFile(ReportType.Xml, "C:\\Temp\\test.xml");
I found a roundabout way to accomplish what I needed by reading the registry keys located in "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History" for applied group policies, added them to an ArrayList then checked to see if the list contained the policy I'm interested in.
To make sure these keys are dynamically updated, I removed the machine in question from the GPO group, rebooted and the keys associated with that policy were removed.
ArrayList groupPolicies = new ArrayList();
using (RegistryKey historyKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History"))
{
foreach (string historySubkey in historyKey.GetSubKeyNames())
{
using (RegistryKey guidKey = historyKey.OpenSubKey(historySubkey))
{
foreach (string guidsubkey in guidKey.GetSubKeyNames())
{
using (RegistryKey keyvalue = guidKey.OpenSubKey(guidsubkey))
{
groupPolicies.Add(keyvalue.GetValue("DisplayName"));
//Console.WriteLine(keyvalue.GetValue("DisplayName"));
}
}
}
}
}
if (!groupPolicies.Contains("replacewithyourGPOname"))
{
Console.WriteLine("The machine is not a member of the policy");
}

Deleting registry key based on one of it's values?

I'm working on a simple application to delete user profile entries from the registry, but I've ran into an issue.
So first, I'm getting all the subkeys that are in the ProfileList through the following code:
List<string> KeyList = new List<string>();
RegistryKey ProfileList = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\\Microsoft\Windows NT\\CurrentVersion\\ProfileList\\");
foreach (string ProfileKey in ProfileList.GetSubKeyNames())
{
KeyList.Add(ProfileKey);
}
From there, I'm getting the ProfileImagePath value of each of those keys and adding them to a checked list box:
KeyList.ForEach(delegate(string ProfileKey)
{
ProfileList = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\\Microsoft\Windows NT\\CurrentVersion\\ProfileList\\" + ProfileKey + "\\");
checkedListBox1.Items.Add(ProfileList.GetValue("ProfileImagePath").ToString());
});
Then, when the user clicks the delete button, I want the application to delete the user profiles that are checked. However, I would have to get the value of each checked item (which looks something like C:/Users/Name) and determine which registry keys to delete. I assume I can do this in a foreach loop, but I'm not quite sure how.
What is the best way to go around doing this?
Thanks.
Here you go. You could execute this code when the user clicks a button such as "Delete Selected Users". Here is the shell of the code:
string[] CheckItemsArray = new string[checkedListBox1.CheckedItems.Count+1];
checkedListBox1.CheckedItems.CopyTo(CheckItemsArray, 0);
foreach (string CheckedItem in CheckItemsArray)
{
if (CheckedItem != null)
{
//your deleting logic here
}
}

Get Safe sender list in Outlook 2007 C# Add in

I have created an Outlook 2007 add-in in C#.NET 4.0.
I want to read the safe sender list in my C# code.
if (oBoxItem is Outlook.MailItem)
{
Outlook.MailItem miEmail = (Outlook.MailItem)oBoxItem;
OlDefaultFolders f = Outlook.OlDefaultFolders.olFolderContacts;
if (miEmail != null)
{
string body = miEmail.Body;
double score = spamFilterObject.CalculateSpamScore(body);
if (score <= 0.9)
{
miEmail.Move(mfJunkEmail);
}
}
}
So, the above code moves all email to spam, even though they are present in the safe sender list. Thus I want to get the safe sender list so that I can avoid this spam checking.
Could anybody please help me on this?
The Outlook object model doesn't expose these lists (for more or less obvious reasons). The safe sender list can be read straight from the registry at:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\[PROFILE NAME]\0a0d020000000000c000000000000046\001f0418
This binary registry key contains double-byte characters, separated by a semicolon (;).
The MAPI property mapping onto this registry key is
PR_SPAM_TRUSTED_SENDERS_W, documented here.
Chavan, I assume since this hasn't been updated in over 4 years, you don't need any more information, but this question and the answer helped me find what I was looking for (it was very hard to find) and enabled me to write the code below that may help if you're still looking for an answer.
This code runs in LINQPad, so if you aren't a LINQPad user, remove the .Dump() methods and replace with Console.WriteLine or Debug.WriteLine.
Cheers!
const string valueNameBlocked = "001f0426";
const string valueNameSafe = "001f0418";
// Note: I'm using Office 2013 (15.0) and my profile name is "Outlook"
// You may need to replace the 15.0 or the "Outlook" at the end of your string as needed.
string keyPath = #"Software\Microsoft\Office\15.0\Outlook\Profiles\Outlook";
string subKey = null;
var emptyBytes = new byte[] { };
var semi = new[] { ';' };
string blocked = null, safe = null;
// I found that my subkey under the profile was not the same on different machines,
// so I wrote this block to look for it.
using (var key = Registry.CurrentUser.OpenSubKey(keyPath))
{
var match =
// Get the subkeys and all of their value names
key.GetSubKeyNames().SelectMany(sk =>
{
using (var subkey = key.OpenSubKey(sk))
return subkey.GetValueNames().Select(valueName => new { subkey = sk, valueName });
})
// But only the one that matches Blocked Senders
.FirstOrDefault(sk => valueNameBlocked == sk.valueName);
// If we got one, get the data from the values
if (match != null)
{
// Simultaneously setting subKey string for later while opening the registry key
using (var subkey = key.OpenSubKey(subKey = match.subkey))
{
blocked = Encoding.Unicode.GetString((byte[])subkey.GetValue(valueNameBlocked, emptyBytes));
safe = Encoding.Unicode.GetString((byte[])subkey.GetValue(valueNameSafe, emptyBytes));
}
}
}
// Remove empty items and the null-terminator (sometimes there is one, but not always)
Func<string, List<string>> cleanList = s => s.Split(semi, StringSplitOptions.RemoveEmptyEntries).Where(e => e != "\0").ToList();
// Convert strings to lists (dictionaries might be preferred)
var blockedList = cleanList(blocked).Dump("Blocked Senders");
var safeList = cleanList(safe).Dump("Safe Senders");
byte[] bytes;
// To convert a modified list back to a string for saving:
blocked = string.Join(";", blockedList) + ";\0";
bytes = Encoding.Unicode.GetBytes(blocked);
// Write to the registry
using (var key = Registry.CurrentUser.OpenSubKey(keyPath + '\\' + subKey, true))
key.SetValue(valueNameBlocked, bytes, RegistryValueKind.Binary);
// In LINQPad, this is what I used to view my binary data
string.Join("", bytes.Select(b => b.ToString("x2"))).Dump("Blocked Senders: binary data");
safe = string.Join(";", safeList) + ";\0"; bytes = Encoding.Unicode.GetBytes(safe);
string.Join("", bytes.Select(b => b.ToString("x2"))).Dump("Safe Senders: binary data");
PST and IMAP4 (ost) stores keep the list in the profile section in the registry. Profile section guid is {00020D0A-0000-0000-C000-000000000046}. To access the data directly, you will need to know the Outlook version and the profile name.
Exchange store keeps this data as a part of the server side rule that processes incoming messages on the server side. You can see the rule data in OutlookSpy (I am its author) - go to the Inbox folder, "Associated Contents" tab, find the entry named (PR_RuleMsgName) == "Junk E-mail Rule", double click on it, take a look at the PR_EXTENDED_RULE_CONDITION property.
Outlook Object Model does not expose Junk mail settings. If using Redemption (I am also its author) is an option, it exposes the RDOJunkEmailOptions.TrustedSenders collection (works both for the PST and Exchange stores):
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Store = Session.Stores.DefaultStore
set TrustedSenders = Store.JunkEmailOptions.TrustedSenders
for each v in TrustedSenders
debug.print v
next

Categories

Resources