Getting all startup items? - c#

Ok, I guess I'm having a brain fart here and cant find my way out of it. What I'm trying to accomplish is to list all startup items (applications, processes, etc) and display them on a form (like what you get with msconfig.exe). I thought this code would do it:
private List<StartupItems> getStartupItems()
{
try
{
ManagementClass cls = new ManagementClass("Win32_StartupCommand");
ManagementObjectCollection coll = cls.GetInstances();
List<StartupItems> items = new List<StartupItems>();
foreach (ManagementObject obj in coll)
{
items.Add(
new StartupItems
{
Command = obj["Command"].ToString(),
Description = obj["Description"].ToString(),
Name = obj["Name"].ToString(),
Location = obj["Location"].ToString(),
User = obj["User"].ToString()
});
}
return items;
}
catch (Exception ex)
{
_message = ex.ToString();
_status = false;
return null;
}
But all that gets are the enabled ones with my username. What I'm trying to get is all items, either my username or system, all the enabled ones and all the disabled ones as well (just like msconfig). I've done tons of searching and cannot find anything really any different than what I'm using.

Have you considered reading directly from the registry?
One alternative would be to run autorunssc (it's the command-line version of autoruns) in the background and read its response.

Related

Can't retrieve application rules with HNetCfg.FwMgr + AuthorizedApplications

I'm trying to retrieve all authorized applications with C#:
ArrayList result = new ArrayList();
INetFwMgr firewallManager = (INetFwMgr)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwMgr"));
foreach (INetFwAuthorizedApplication app in firewallManager.LocalPolicy.CurrentProfile.AuthorizedApplications)
{
Console.WriteLine(app.Name);
}
The AuthorizedApplications is empty, but in Control Panel I can see many rules, enabled or not:
What was wrong? I tried other profiles, e.g DOMAIN/STANDARD, same result.
console.write(result); check if forEach method brings you all aplications authorized with C# should be a loop instead
foreach (INetFwAuthorizedApplication app in
firewallManager.LocalPolicy.CurrentProfile.AuthorizedApplications)
{
Console.WriteLine(app.Name);
}e.g for(INetFwAuthorizedApplication app in
firewallManager.LocalPolicy.CurrentProfile.AuthorizedApplications){console.log(app.Name);} Are you sure Name is the correct value?, shouldn't be app.name?
It seems you can iterate the app list, but you are not finding the correct name for app. Use name instead Name. Try console.WriteLine(app.name) or console.WriteLine(app.GetName)
Maybe try this:
public List<Object>(String name){
ArrayList result = new ArrayList();
INetFwMgr firewallManager =
(INetFwMgr)Activator.CreateInstance
(Type.GetTypeFromProgID("HNetCfg.FwMgr"));
foreach (INetFwAuthorizedApplication app in
firewallManager.LocalPolicy
.CurrentProfile.AuthorizedApplications)
{
if(app.Name == _name){
app.Name = name;
Console.WriteLine(app.Name);
}
}
return result;
}

Bug in SSRS CreateFolder C# command?

I think I've come across a bug in the CreateFolder command in the Reportingservices2010 SOAP API
The test scenario is I'm trying to create a folder (named Sales Dashboard) in the same Parent folder (lets say Sales) as a report also named Sales Dashboard.
The command completed with the "AlreadyExists" Exception when the folder does not already exist. It looks like the method isn't checking the catalog item type.
Here's my code:
public static void createFolders(string targetURL, string folderName, string parentPath, string description, string visible)
{
//Build Authentication
ReportingService2010 rs = new ReportingService2010();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs.Url = targetURL;
//Declare properties
Property descriptionProp = new Property();
Property visibleProp = new Property();
Property[] props = new Property[2];
descriptionProp.Name = "Description";
descriptionProp.Value = description;
visibleProp.Name = "Visible";
visibleProp.Value = visible;
props[0] = descriptionProp;
props[1] = visibleProp;
try
{
rs.CreateFolder(folderName, parentPath, props);
}
catch(Exception ex)
{
if(ex.Message.Contains("AlreadyExists"))
{
//do nothing?
}
else
{
throw;
}
}
}
I wanted to see if I could contribute a fix but there's no GitHub repo for the C# SSRS stuff. Any thought's on a workaround?
The API is returning the correct error since this is a restriction of Reporting Services in general: items within the same folder must have unique names (regardless of item type).

How to get the MessageId from all exchange items

Hello I recently got into development around EWS. One of the issue came up to me is that a client ask me to import emails into database and he wants to detect the duplicate based on InternetMessageID this way he doesn't have to import the duplicate emails and my code came up to this point.
private static string GetInternetMessageID(Microsoft.Exchange.WebServices.Data.Item email)
{
EmailMessage emailMsg = email as EmailMessage;
string returnId = string.Empty;
if ((emailMsg != null)) {
try {
emailMsg.Load();
//loads additional info, without calling this ToRecipients (and more) is empty
} catch (ArgumentException ex) {
//retry
email.Load();
}
returnId = emailMsg.InternetMessageId;
} else {
//what to do?
}
return returnId;
}
I can handle regular emails, but for special exchange objects such as contact, Calendar, Posts etc it does not work because it could not cast it to an EmailMessage object.
And I know you can extract the internetMessageId from those objects. Because the client used to have another software that extract this ID for them, maybe the property is not called internetMessageID, I think I probally have to extract it from the internetMessageHeader. However when ever I try to get it from the item object it just throws me an error. How do I get the internet messageID from these "Special" exchange items?
PS i am aware of item.id.UniqueID however that is not what I want as this id changes if I move items from folder to another folder in exchange
Only objects that have been sent via the Transport service will have an InternetMessageId so things like Contacts and Tasks because they aren't messages and have never been routed via the Transport service will never have an Internet MessageId. You probably want to look at using a few properties to do this InternetMessageId can be useful for messages PidTagSearchKey https://msdn.microsoft.com/en-us/library/office/cc815908.aspx is one that can be used (if you good this there are various examples of using this property).
If your going to use it in Code don't use the method your using to load the property on each item this is very inefficient as it will make a separate call for each object. Because these I'd's are under 256 Kb just retrieve then when using FindItems. eg
ExtendedPropertyDefinition PidTagSearchKey = new ExtendedPropertyDefinition(0x300B, MapiPropertyType.Binary);
ExtendedPropertyDefinition PidTagInternetMessageId = new ExtendedPropertyDefinition(0x1035, MapiPropertyType.String);
PropertySet psPropSet = new PropertySet(BasePropertySet.IdOnly);
psPropSet.Add(PidTagSearchKey);
psPropSet.Add(PidTagInternetMessageId);
ItemView ItemVeiwSet = new ItemView(1000);
ItemVeiwSet.PropertySet = psPropSet;
FindItemsResults<Item> fiRess = null;
do
{
fiRess = service.FindItems(WellKnownFolderName.Inbox, ItemVeiwSet);
foreach (Item itItem in fiRess)
{
Object SearchKeyVal = null;
if (itItem.TryGetProperty(PidTagSearchKey, out SearchKeyVal))
{
Console.WriteLine(BitConverter.ToString((Byte[])SearchKeyVal));
}
Object InternetMessageIdVal = null;
if (itItem.TryGetProperty(PidTagInternetMessageId, out InternetMessageIdVal))
{
Console.WriteLine(InternetMessageIdVal);
}
}
ItemVeiwSet.Offset += fiRess.Items.Count;
} while (fiRess.MoreAvailable);
If you need larger properties like the Body using the LoadPropertiesForItems Method https://blogs.msdn.microsoft.com/exchangedev/2010/03/16/loading-properties-for-multiple-items-with-one-call-to-exchange-web-services/

Searching user tasks by task.body text

Good morning all! I have spent a good bit of time searching and reading forums about this, but I can't seem to find a solution. Any help you all can offer is greatly appreciated.
I have created an Outlook Add-In via C# and Visual Studio 2013. This add-in will create a number of custom tasks, which is working. The problem I am having is searching for those custom created tasks and deleting them. I have code working to search based on a strict subject line, but nothing using "LIKE" to find partial search matches. I've also read that the find method cannot search the body, so then advanced search is better. I am trying to work with the advanced search documentation I can find, but am not sure of what the "scope" parameter would be for tasks, or even if this is the best solution.
I figured the best approach was to append all custom created tasks with a footer notated "DO NOT DELETE" and output text here that I could search to determine the task was created by my add-in and then delete it. I have also considered storing the custom task's EntryID at the time of creation, but have read that this number can change, so I am not sure this will be the best method to always find and delete the custom created tasks.
I am hoping one of you would be able to assist with a code sample of searching a user's task folder for all tasks containing a string in the body of the task. Alternatively, I can definitely work with a search of all tasks containing a string in the subject line. I am pulling my hair out over this, and I appreciate any guidance, articles, or code samples you all can provide! I either find examples in VB, or partial explanations that I am unable to put into practice.
EDIT: SOLVED
Thanks to the below response marked as an answer, I wanted to give more code detail here in case anybody needs a more detailed answer in the future. This solution does not search the body text as stated in this post title as that solution was not the best way to accomplish what I needed.
Creating the task
using Outlook = Microsoft.Office.Interop.Outlook;
Outlook.Application app = new Outlook.Application();
Outlook.TaskItem task = app.CreateItem(Outlook.OlItemType.olTaskItem) as Outlook.TaskItem;
Outlook.UserProperties taskUserProperties = null;
Outlook.UserProperty taskUserProperty = null;
try {
taskUserProperties = task.UserProperties;
taskUserProperty = taskUserProperties.Add("Custom Property Name", Outlook.OlUserPropertyType.olText, true, 1);
taskUserProperty.Value = "Custom value";
task.Save();
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
finally {
if (taskUserProperty != null) Marshal.ReleaseComObject(taskUserProperty);
if (taskUserProperties != null) Marshal.ReleaseComObject(taskUserProperties);
}
Finding it
string searchCriteria = "[Custom Property Name] = 'VALUE TO FIND'";
Outlook.Application app = new Outlook.Application();
Outlook._NameSpace ns = app.GetNamespace("MAPI");
Outlook.MAPIFolder folder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderTasks);
Outlook._TaskItem taskItem = null;
Outlook.Items folderItems = null;
object resultItem = null;
try {
folderItems = folder.Items;
folderItems.IncludeRecurrences = true;
if (folderItems.Count > 0) {
resultItem = folderItems.Find(searchCriteria);
if (resultItem != null) {
if (resultItem is Outlook._TaskItem) {
taskItem = resultItem as Outlook._TaskItem;
MessageBox.Show(taskItem.Subject, "Task found!", MessageBoxButtons.OK);
}
}
Marshal.ReleaseComObject(resultItem);
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
finally {
if (folderItems != null) Marshal.ReleaseComObject(folderItems);
}
Why not use the user properties (TaksItem.UserPropertiers.Add)?
If the user fields is added to the folder fields, you can search for that property using Items.Find/FindNext/Restrict.

Reading Group Policy Settings using C#

How do I go about iterating over available and/or set settings in a given GPO (using name or GUID) in an AD domain? Without having to export to XML/HTML using powershell, etc.
I'm using C# (.NET 4.0).
That question got me hyped so I went to research it. So a +1
Some solutions I found from the top being the best to bottom being the worst
A good explanation with an example and example script!
This one, tells you to go through the registry but you gotta figure out who to access the AD
Pinvoke: Queries for a group policy override for specified power settings.
I had a similar problem, and didn't want to download and install the Microsoft GPO library (Microsoft.GroupPolicy.Management). I wanted to do it all with System.DirectoryServices. It took a little digging, but it can be done.
First retrieve your container using DirectorySearcher. You'll need to have already opened a directory entry to pass into the searcher. The filter you want is:
string filter = "(&" + "(objectClass=organizationalUnit)" + "(OU=" + container + "))";
and the property you're interested in is named "gPLink", so create an array with that property in it:
string[] requestProperties = { "gPLink" };
Now retrieve the results, and pull out the gPLink, if available.
using (var searcher = new DirectorySearcher(directory, filter, properties, SearchScope.Subtree))
{
SearchResultCollection results = searcher.FindAll();
DirectoryEntry entry = results[0].GetDirectoryEntry();
string gpLink = entry.Properties["gPLink"].Value;
If gpLink is null, there is no GPO associated with the container (OU).
Otherwise, gpLink will contain a string such as this:
"[LDAP://cn={31B2F340-016D-11D2-945F-00C04FB984F9},cn=policies,cn=system,DC=Test,DC=Domain;0]"
In the text above, you can see a CN for the GPO. All we need to do now is retrieve the GPO from the DC.
For that, we use a filter that looks like this:
string filter = "(&" +
"(objectClass=groupPolicyContainer)" +
"(cn={31B2F340-016D-11D2-945F-00C04FB984F9}))";
You'll want to create a Properties array that include the following:
Properties = { "objectClass", "cn", "distinguishedName", "instanceType", "whenCreated",
"whenChanged", "displayName", "uSNCreated", "uSNChanged", "showInAdvancedViewOnly",
"name", "objectGUID", "flags", "versionNumber", "systemFlags", "objectCategory",
"isCriticalSystemObject", "gPCFunctionalityVersion", "gPCFileSysPath",
"gPCMachineExtensionNames", "dSCorePropagationData", "nTSecurityDescriptor" };
Now use DirectorySearcher to retrieve the GPO. You'll get back a DirectoryEntry in the results that contains all of the above fields in the Properties collection. Some are COM objects, so you'll have to handle those appropriately.
Here is a better and more complete example then above.
class Program
{
static void Main(string[] args)
{
DirectoryEntry rootDse = new DirectoryEntry("LDAP://rootDSE");
DirectoryEntry root = new DirectoryEntry("GC://" + rootDse.Properties["defaultNamingContext"].Value.ToString());
DirectorySearcher searcher = new DirectorySearcher(root);
searcher.Filter = "(objectClass=groupPolicyContainer)";
foreach (SearchResult gpo in searcher.FindAll())
{
var gpoDesc = gpo.GetDirectoryEntry().Properties["distinguishedName"].Value.ToString();
Console.WriteLine($"GPO: {gpoDesc}");
DirectoryEntry gpoObject = new DirectoryEntry($"LDAP://{gpoDesc}");
try
{
Console.WriteLine($"DisplayName: {gpoObject.Properties["displayName"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"PCFileSysPath: {gpoObject.Properties["gPCFileSysPath"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"VersionNumber: {gpoObject.Properties["versionNumber"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"UserExtensionNames: {gpoObject.Properties["gPCUserExtensionNames"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"MachineExtensionNames: {gpoObject.Properties["gPCMachineExtensionNames"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"PCFunctionality: {gpoObject.Properties["gPCFunctionalityVersion"].Value.ToString()}");
}
catch
{
}
}
Console.ReadKey();
}
}
UPDATED: Working copy. You can now use c# to get read and parse a given GPO without having to use Powershell or write anything to disk.
using Microsoft.GroupPolicy;
var guid = new Guid("A7DE85DE-1234-F34D-99AD-5AFEDF7D7B4A");
var gpo = new GPDomain("Centoso.local");
var gpoData = gpo.GetGpo(guid);
var gpoXmlReport = gpoData.GenerateReport(ReportType.Xml).ToString();
using (XmlReader reader = XmlReader.Create(new StringReader(gpoXmlReport)))
{
string field;
while (reader.MoveToNextAttribute())
{
foreach (string attr in attributes)
{
// do something
}
}
}
This uses the Group Policy Management Console (GPMC) tools:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa814316(v=vs.85).aspx
Microsoft.GroupPolicy Namespace
https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.grouppolicy(v=vs.85).aspx

Categories