Trying to create a startup manager using .net 2.0 - c#

OK so I'm working on a integrated start-up manager with check boxes, so far this is what i have, it does this on form load:
RegistryKey hklm = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
foreach (string Programs in hklm.GetValueNames())
{
string GetValue = hklm.GetValue(Programs).ToString();
ListViewItem item1 = listView1.Items.Add(Programs);
item1.SubItems.Add(hklm.Name.ToString().Replace("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion", "HKLM"));
item1.SubItems.Add(GetValue);
}
RegistryKey hkcu = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
foreach (string Programs in hkcu.GetValueNames())
{
string GetValue = hkcu.GetValue(Programs).ToString();
ListViewItem item2 = listView1.Items.Add(Programs);
item2.SubItems.Add(hkcu.Name.ToString().Replace("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion", "HKCU"));
item2.SubItems.Add(GetValue);
}
i know its probably a bit sloppy but it seems to work. now what id like to know is, if i have check boxes enabled in the list view... how can i have it:
A: Check the ones that are "enabled"/not check the ones that are "Disabled"
B: make it so when you check one it "enables" it or uncheck one it "disables" it?
OR!
(preferred) make a context menu (right click menu) for disabling and re-enabling each entry (and disabling it would mean making a sub key called something like "Disabled Start" that it would move keys to and enabling them would move them back into the previous key)
i know for enabling/disabling you can just move the key to a different subkey for safe keeping, correct? or do i have this all wrong?

I agree with you . and i world do this if i were you . :)
I think you can either store those disabled keys to a file stored in your app directory. you know , sth like ini file. or you can store them in the registry with a key created by yourself. so you can delete them when uninstalling the manager.

Well the recommended procedure would be so actually save those entries into text files. I storngly suggest that you use Isolated Storage and even stronger if you are going to be building this for a network.
I dunno much about this but I think you could also export the entries into files (which could also be IsolatedStorageFiles) just like this guy seems to have done (look for the "ExportKey" method) and then re-import them. Note that in this case you would still need to have some sort of mechanism to remember the entries so you can show them in the list view.
Regarding the context menu I think this might be what you want, but I just actually google it and running Ubuntu so I can't really try it out before.

Related

How to remove one entry from a REG_MULTI_SZ key without Deleting other entries under the same Multi-String

I am currently writing an App to replace the Manual uninstall process my company has in place for removing our SQL instance.
I need to be able to Remove "ACT7" from the "InstalledInstances" Multi-String in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server, without removing other SQL instance names.
I have found a few articles online that detail how to replace what the Multi-string has in it, however, they overwrite the whole thing and so would get rid of other instance names.
I need to be able to either, just remove "ACT7" from the list, or Copy all entries apart from "ACT7" and create a replacement key with just those values.
This is the first App I have written, and this is the last key I need to change. Any help would be amazing.
A REG_MULTI_SZ value is logically a single value; the only way to remove parts of it is to replace it in its entirety.
const string instanceKey = #"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server";
const string instanceName = "ACT7";
List<string> instances =
(
(string[]) Registry.GetValue(instanceKey, "InstalledInstances", new string[] {})
).ToList();
if (instances.Remove(instanceName)) {
Registry.SetValue(instanceKey, "InstalledInstances", instances.ToArray());
}
Note that this should not be used as a general way to remove SQL Server instances. Having a "manual uninstall process" for SQL Server, as opposed to SQL Server's own setup (with /ACTION=UNINSTALL), is asking for trouble down the road if the manual process fails to remove absolutely everything required.

Set a permanent value of a variable without using a database

I don't know how to describe it thoroughly in the title, but I need to set a permanent value of a variable/flag once a process has return true and maybe set some flag in the program itself the value rather than saving it to database. And once that variable/flag has already have that value then the program won't run the process again and just use the value. Is it possible? I'm using VB.Net. I can't use the database because database can be overridden and change values by using query. Thanks in advance!
You can simply use binary/XML serialization in a file to save the state of that variable through your program. Every time you restart your app you can access the value from that file to get its current state.
You can look at this example - http://www.centerspace.net/examples/nmath/csharp/core/binary-serialization-example.php
Basically, you will not save the value in the database but in a file. Anyways you need to persist the value somewhere.
Some ways below
You did not specify if you are afraid that your application or another one could change the value
How I would do it
My ideas below
1)You could use an xml file for example and zip a copy of it with a strong password. Every time you update the first xml you will update also the encrypted zipped xml.You can use a FileSystemWatcher and capture any file change, so if something/someone has changed the file you just get a new copy from the zip
2)You can store the value in the DB and add a trigger to prevent delete/update
for example
-- delete trigger
CREATE TRIGGER Function_Value_Deleted
ON [dbo].[FunctionsValueTb]
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (
SELECT [Flag] FROM deleted
)
BEGIN
ROLLBACK;
RAISERROR ('Record deletion is not allowed...', 16, 1);
END
END
*You can use also use THROW rather than RAISERROR
**Do the same for the insert and update actions
***You can also store the value into a log table or send an email
I found myself in a situation quite similar to yours a couple of days ago.
In the end, I decided to use the settings functionaly provided by .NET: it is easy to use and maintain, and so far it has given me good results.
Yo can see here what I am talking about:
Best practice to save application settings in a Windows Forms Application
That thread refers to C# but is easily applicable for VB.NET: I just had to follow the same steps in order to add the Settings file:
Right click on the project in Solution Explorer, choose Properties.
Select the Settings tab, click on the hyperlink if settings doesn't
exist. Use the Settings tab to create application settings. Visual
Studio creates the files Settings.settings and
Settings.Designer.settings that contain the singleton class Settings
inherited from ApplicationSettingsBase
And then, from my code, I use the settings like this:
Dim lastExecDate As Date = My.Settings.LastSuccessfulExecution
lastExecDate = lastExecDate.AddDays(1)
// Perform my next execution and do other stuff
My.Settings.LastSuccessfulExecution = lastExecDate
My.Settings.Save()
Next time you retrieve the parameter LastSuccessfulExecution, it will have the updated value.
One more remark, as stated in the post that I linked above:
Note that you need to set the scope property of your settings. If you
select Application scope then Settings.Default.< your property > will
be read-only
Finally, I see that you are using this to store the expiration date of a product, so you don't want the user messing around with it. According to this post, the actual values of the parameters are stored in an Application Data user folder. It is somehow obfuscated since it is not that easy to find and besides it contains a hash on its name... I don't know if that is well hidden enough for you.
If you want the value only to exist in memory when the application is running then you can use the main thread of the application and use:
int slotData = randomGenerator.Next(1, 200);
//to set the data
Thread.SetData(Thread.GetNamedDataSlot("SomeDataKey"), slotData);
//to get the data
int newSlotData = (int)Thread.GetData(Thread.GetNamedDataSlot("SomeDataKey"));
Or you can use the Windows Registry if your app only runs on Windows, if not then you would have to write the value/object to a file and read it from there.

Does IIS Metabase return sites in Id ascending order?

I'm not sure if my question on the face of it makes full sense, so let me try and elaborate. At the moment I try and check if a website already exists in IIS by creating a new DirectoryEntry:
DirectoryEntry IISWebsites = new DirectoryEntry(MetaBasePath);
MetaBasePath is defined earlier as:
private const string MetaBasePath = "IIS://Localhost/W3SVC";
I check IISWebsites children in a foreach loop and just wondered if this will run through the children in Id order? From what I've read this is actually stored in the DirectoryEntry 'Name' property.
The reason I ask is that if the website name entered by the user in my web setup project isn't found then I want to return the highest id so I can add 1 to it and create a new website with the name supplied by the user.
Having tested this with my IIS it does seem to return it in this order but I need to be sure.
EDIT
I've found the following on Microsoft support (http://support.microsoft.com/kb/240941):
Note that when the metabase is searched for configuration information,
it is enumerated from the bottom, or subkey, to top, or node.
This seems to imply that it does do what I think, but it's not 100% clear if it works on site Id as I'm not sure how this relates to the subkey.
The documentation does not specifically define the order as by site ID so it would not be safe to assume it will always be sorted that way (particularly as your current application eventually gets used with new versions of .NET/Windows/IIS in the future).
Most likely the number of websites is not going to be big enough that enumerating them to find the max would not be a bottleneck.
Even so, you can run a search for websites and specify the order using DirectorySearcher.Sort.
Note that in regards to your edit and how configuration information is enumerated, that does not related to sort order. The one sentence taken out of context is not as clear. Read it in context of the whole paragraph and it is clear that the enumeration behavior is related to metabase property inheritance.

Saving contents of a listBox to program settings C#

So what I am trying to do is save the contents from a listBox to the application Properties.Settings.Default
I have no idea where to start, nor do I know if it is even possible. Thanks in advance.
any settings you have setup in Properties-> settings tab should show up like
[your namespace].Properties.Settings.Default.yoursetting = "change";
after you edit your properties always call
[your namespace].Properties.Settings.Default.Save();
the save part got me at first.
for list types use :
it will help if your objects can be converted to and from strings anything more not really sure for anything more complex but I hope this gets you started.
foreach(string s in listbox.Items){[settingscode].add(s);}
something like that anyways.

c# Clean a registry file .reg to remove duplicate entries

A company I work for sometimes uses super mandatory profiles for their users. Unfortunately this can cause lots of issues with user settings not being saved at log off and so on. To work around this a .reg file is run at startup. For some of these settings regmon was used to record making the settings change and a reg file created from this. The trouble with this is their are lots of duplicate entries making it larger and larger each time this has been done. By the way I didn't implement this procedure I just have to live with it.
I am going to attempt to clean this down to it's minimum but am wondering if anyone has done this before. What I am thinking is, I read the lines into an 2d array so:
[HKEY_CURRENT_USER\Software\CELCAT\CT\SAT\Settings]
"OpenTTVS"="0"
"OTTFrmW"="420"
"OTTFrmH"="321"
becomes:
[HKEY_CURRENT_USER\Software\CELCAT\CT\SAT\Settings], "OpenTTVS"="0"
[HKEY_CURRENT_USER\Software\CELCAT\CT\SAT\Settings], "OTTFrmW"="420"
[HKEY_CURRENT_USER\Software\CELCAT\CT\SAT\Settings], "OTTFrmH"="321"
Then remove duplicates in reverse order so if a setting is changed twice it removes the entries first in the file.
Then sort the array by the hive and output the key every time and the hive when it changes. Sorry if the terminology is wrong.
Will this work? Probably better using a collection rather than an array but you get the idea.
For a first try i would read this .reg file into a tree, just the way regedit looks like. By building up the tree you just check if a node exists. If not, created it else overwrite the existing value.
So you'll get just the last entry which take into effect. After creating this tree, you'll have to read back the current tree and you're ready.
While writing this, i'll got another idea:
Open the .reg file in a texteditor. Replace "[HKEY_CURRENT_USER\" against "[HKEY_CURRENT_USER\JustSomeKeyThatDoesNotExists" and import this file into the registry. Now open the registry and export the whole "[HKEY_CURRENT_USER\JustSomeKeyThatDoesNotExists" back into a file. Open the file and make the first replacement backwards.
Now you'll have a file with unique value in a sorted order. ;-))
You could use a Dictionary of Dictionaries. In pseudo code, you could then do something like this:
Dictionary<String, Dictionary<String, String>> regSettings
Dictionary<String, String> current
for line in sourcefile {
if line.startswith("[") {
if !regSettings.haskey(line) {
regSettings.add(line, new Dictionary<String, String>() )
}
current = regSettings[line]
} else {
key, value = line.split("=")
current[key] = value;
}
}
There are some details to account for (blank lines, comments, poorly remembered function names that should be adjusted for C#...), but that's the basic idea. When you come across a duplicate setting, the later value will replace the older one in the collection. To write the file, just output the reg header, then iterate your collections, writing the top-level key name, followed by all values for that key.

Categories

Resources