I am fairly new to c#. I would like to achieve deleting multiple registry entries one after the other but I am getting exception for the first key and after that the code stops deleting other keys.I have tried below mentioned code it works for single key in if block
string[] keyArray = { #"Wow6432Node\CLSID",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Settings",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Stats",
#"SOFTWARE\Classes\Wow6432Node\CLSID",
#"SOFTWARE\Wow6432Node\Classes\CLSID",
#"Wow6432Node\Microsoft\Code Store Database\Distribution Units",
#"Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage"
};
foreach (var key in keyArray)
{
try
{
RegistryKey myKey = Registry.ClassesRoot.OpenSubKey(key, true);
if (myKey != null)
{
/*Cisco Secure Desktop*/
myKey.DeleteSubKeyTree("{705EC6D4-B138-4079-A307-EF13E4889A82}");
myKey.DeleteSubKeyTree("{F8FC1530-0608-11DF-2008-0800200C9A66}");
myKey.DeleteSubKeyTree("{E34F52FE-7769-46CE-8F8B-5E8ABAD2E9FC}");
/*Cisco Hostscan*/
myKey.DeleteSubKeyTree("{F8FC1530-0608-11DF-2008-0800200C9A66}");
myKey.DeleteSubKeyTree("{E34F52FE-7769-46CE-8F8B-5E8ABAD2E9FC}");
/*Cisco AnyConnect Secure Mobility Client*/
myKey.DeleteSubKeyTree("{55963676-2F5E-4BAF-AC28-CF26AA587566}");
myKey.DeleteSubKeyTree("{CC679CB8-DC4B-458B-B817-D447B3B6AC31}");
}
else
Console.WriteLine(string.Format("could not open key: {0}", key));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(
string.Format("action {0} failed with\n{1}", key, ex.Message));
}
}
Given to your details you may try the following code
string[] keyArray = { #"Wow6432Node\CLSID",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Settings",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Stats",
#"Wow6432Node\Microsoft\Code Store Database\Distribution Units",
#"Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage",
};
foreach (var key in keyArray)
{
try
{
RegistryKey myKey = Registry.ClassesRoot.OpenSubKey(key, true);
if (myKey != null)
myKey.DeleteSubKeyTree("{55963676-2F5E-4BAF-AC28-CF26AA587566}");
else
System.Diagnostics.Debug.WriteLine(string.Format("could not open key: {0}", key));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(
string.Format("action {0} failed with\n{1}", key, ex.Message));
}
}
This should print out some error information, too.
As of your given comment ArgumentException(...) you try to open/delete a subkey {55963676-2F5E-4BAF-AC28-CF26AA587566} that does not exist! Perhaps you should have a look into Registry.OpenSubKey and DeleteSubKeyTree(..)
EDIT: added a new answer as of given details
private static void deleteRegistryKeys2()
{
string[] classIds = {
"{538793D5-659C-4639-A56C-A179AD87ED44}",
/*Cisco Secure Desktop*/
"{705EC6D4-B138-4079-A307-EF13E4889A82}",
"{F8FC1530-0608-11DF-2008-0800200C9A66}",
/*Cisco Hostscan*/
"{F8FC1530-0608-11DF-2008-0800200C9A66}",
"{E34F52FE-7769-46CE-8F8B-5E8ABAD2E9FC}",
/*Cisco AnyConnect Secure Mobility Client*/
"{55963676-2F5E-4BAF-AC28-CF26AA587566}",
"{CC679CB8-DC4B-458B-B817-D447B3B6AC31}"
};
string[] regKeys = { #"Wow6432Node\CLSID",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Settings",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Stats",
#"SOFTWARE\Classes\Wow6432Node\CLSID",
#"SOFTWARE\Wow6432Node\Classes\CLSID",
#"Wow6432Node\Microsoft\Code Store Database\Distribution Units",
#"Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage"
};
// iterate every regKey
foreach (var regkey in regKeys)
{
// go for each classId
foreach (var classId in classIds)
{
// get a regKey within a hive, pass classId too
deleteKey(Registry.ClassesRoot.OpenSubKey(regkey, true), classId);
deleteKey(Registry.CurrentUser.OpenSubKey(regkey, true), classId);
deleteKey(Registry.LocalMachine.OpenSubKey(regkey, true), classId);
}
}
Console.WriteLine("Cleanup finished. Press any key to exit");
Console.ReadLine();
}
private static void deleteKey(RegistryKey registryKey, string classId)
{
// check if there is a key
if (registryKey != null)
{
try
{
// try to remove classId within this regKey
registryKey.DeleteSubKeyTree(classId);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Console.WriteLine(
string.Format("could not delete key {0} with classId {1}",
registryKey, classId));
}
}
}
Finally I have better code which is working after lot of effort Please let me know if anyone can do it better
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string[] clsids = {
"{538793D5-659C-4639-A56C-A179AD87ED44}",
/*Cisco Secure Desktop*/
"{705EC6D4-B138-4079-A307-EF13E4889A82}",
"{F8FC1530-0608-11DF-2008-0800200C9A66}",
/*Cisco Hostscan*/
"{F8FC1530-0608-11DF-2008-0800200C9A66}",
"{E34F52FE-7769-46CE-8F8B-5E8ABAD2E9FC}",
/*Cisco AnyConnect Secure Mobility Client*/
"{55963676-2F5E-4BAF-AC28-CF26AA587566}",
"{CC679CB8-DC4B-458B-B817-D447B3B6AC31}"
};
string[] keys = { #"Wow6432Node\CLSID",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Settings",
#"Software\Microsoft\Windows\CurrentVersion\Ext\Stats",
#"SOFTWARE\Classes\Wow6432Node\CLSID",
#"SOFTWARE\Wow6432Node\Classes\CLSID",
#"Wow6432Node\Microsoft\Code Store Database\Distribution Units",
#"Wow6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ModuleUsage"
};
/*Classes root hive*/
for (int i = 0; i<=7; i++ )
{
foreach (var regkey in keys)
{
try
{
using (RegistryKey mykey = Registry.ClassesRoot.OpenSubKey(regkey, true))
if (mykey != null)
{
Console.WriteLine(mykey + #"\"+clsids[i]);
mykey.DeleteSubKeyTree(clsids[i]);
}
else
{
Console.WriteLine("key does not exist");
}
/*try end*/
}
catch
{
continue;
}
}
}
/*Current user hive*/
for (int i = 0; i <= 7; i++)
{
foreach (var regkey in keys)
{
try
{
using (RegistryKey mykey = Registry.CurrentUser.OpenSubKey(regkey, true))
if (mykey != null)
{
Console.WriteLine(mykey + #"\" + clsids[i]);
mykey.DeleteSubKeyTree(clsids[i]);
}
else
{
Console.WriteLine("key does not exist");
}
/*try end*/
}
catch
{
continue;
}
}
}
/*Local Machine hive*/
for (int i = 0; i <= 7; i++)
{
foreach (var regkey in keys)
{
try
{
using (RegistryKey mykey = Registry.LocalMachine.OpenSubKey(regkey, true))
if (mykey != null)
{
Console.WriteLine(mykey + #"\" + clsids[i]);
mykey.DeleteSubKeyTree(clsids[i]);
}
else
{
Console.WriteLine("key does not exist");
}
/*try end*/
}
catch
{
continue;
}
}
}
Console.WriteLine("Cleanup finished. Press any key to exit");
Console.ReadLine();
}
}
}
Related
I want to access the RegistryKeys of a remote PC in my network, if there is no terminalNumber passed as a parameter.
public LoginEntity(string ipAdress, string username, string password, string terminalNumber = "")
{
this.IpAdress = ipAdress;
this.Username = username;
this.Password = password;
if (terminalNumber == "")
{
try
{
RegistryKey rKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, IpAdress, RegistryView.Registry64);
rKey = rKey.OpenSubKey(#"SOFTWARE\Test", RegistryKeyPermissionCheck.ReadWriteSubTree);
var key = rKey.GetValue("terminalNumber", "NOTFOUND");
if (key is string)
{
if ((string)key != "NOTFOUND")
this.TerminalNumber = (string)key;
}
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine("UnauthorizedException: Calling TerminalNumber from Remote Registry Keys");
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine("IOException: Remote PC not available");
}
}
else
this.TerminalNumber = terminalNumber;
}
Due to safety reasons the Subkey in this example is called 'Test'.
But at
RegistryKey rKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, IpAdress, RegistryView.Registry64);
the application throws an UnauthorizedAccessException.
What I did:
I already run Visual Studio 2019 as an administator.
The LoginEntity was instantiated in a Task*. (As I am using WPF, I don't want my UI to freeze, so I run it in a Task).
*The Task call is located in the MainWindow()-Constructor of my WPF-Application
Task.Run(() =>
{
List<LoginEntity> loginUser = Utility.ReadLoginDataFromCsv(loginUserPath);
this.Dispatcher.Invoke(() =>
{
Listview.ItemsSource = loginUser;
lblUserLoading.Content = "";
});
});
public static List<LoginEntity> ReadLoginDataFromCsv(string path, bool ignoreFirstLine = false)
{
List<LoginEntity> list = new List<LoginEntity>();
var lines = File.ReadAllLines(path, Encoding.UTF8);
if (ignoreFirstLine)
lines = lines
.Skip(1)
.ToArray();
foreach (string line in lines)
{
var rowData = line.Split(';');
LoginEntity le = new LoginEntity(rowData[0], rowData[1], rowData[2], rowData[3]);
if (le.IpAdress != "" && le.Username != "" && le.Password != "")
list.Add(le);
}
return list;
}
Does anyone know why I get the UnAuthorizedException and how I can get rid of it?
I will be straight forward and say that I found this code online and therefore is not my own. It works perfectly if I type in the name of the program as shown in Programs and Features but for instance, I want to type Mozilla Firefox and have it find the installed Mozilla Firefox 26.0 (x86 en-US). I tried many times to use .substring and .contains in the line that checks the two strings but each time leads the program to just lock up. Any help is appreciated.
Just for side notes:
I am using a list of programs in a txt file that are read in to check against the installed apps.
I ran a messagebox right after it sets the display name and several of the message boxes show up blank. I tried to limit it with string.length not being 0 and length being equal or greater than the string from the txt file but all still locks up the program.
Code:
private static bool IsAppInstalled(string p_machineName, string p_name)
{
string keyName;
// search in: CurrentUser
keyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
if (ExistsInRemoteSubKey(p_machineName, RegistryHive.CurrentUser, keyName, "DisplayName", p_name) == true)
{
return true;
}
// search in: LocalMachine_32
keyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
if (ExistsInRemoteSubKey(p_machineName, RegistryHive.LocalMachine, keyName, "DisplayName", p_name) == true)
{
return true;
}
// search in: LocalMachine_64
keyName = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
if (ExistsInRemoteSubKey(p_machineName, RegistryHive.LocalMachine, keyName, "DisplayName", p_name) == true)
{
return true;
}
return false;
}
private static bool ExistsInRemoteSubKey(string p_machineName, RegistryHive p_hive, string p_subKeyName, string p_attributeName, string p_name)
{
RegistryKey subkey;
string displayName;
using (RegistryKey regHive = RegistryKey.OpenRemoteBaseKey(p_hive, p_machineName))
{
using (RegistryKey regKey = regHive.OpenSubKey(p_subKeyName))
{
if (regKey != null)
{
foreach (string kn in regKey.GetSubKeyNames())
{
using (subkey = regKey.OpenSubKey(kn))
{
displayName = subkey.GetValue(p_attributeName) as string;
MessageBox.Show(displayName);
if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true) // key found!
{
return true;
}
}
}
}
}
}
return false;
}
I have tried too many different things to list (or remember)... If it helps this is the majority of the rest of the code calling it:
private void Button_Click(object sender, EventArgs e)
{
string[] lines = new string[250];
string msg = "";
string path = System.Windows.Forms.Application.StartupPath;
if (blah.Checked)
{
try
{
StreamReader filePick = new StreamReader(#path + "\\blah.txt");
int counter = 0;
while ((lines[counter] = filePick.ReadLine()) != null)
{
counter++;
}
filePick.Close();
}
catch (Exception ex)
{
msg += ex.Message;
}
}
else if (blah2.Checked)
{
try
{
StreamReader filePick = new StreamReader(#path + "\\blah2.txt");
int counter = 0;
while ((lines[counter] = filePick.ReadLine()) != null)
{
counter++;
}
filePick.Close();
}
catch (Exception ex)
{
msg += ex.Message;
}
}
string MACHINE_NAME = System.Environment.MachineName;
int counter2 = 0;
string APPLICATION_NAME = "";
string filename = "";
while (lines[counter2] != null)
{
APPLICATION_NAME = lines[counter2];
try
{
bool isAppInstalled = IsAppInstalled(MACHINE_NAME, APPLICATION_NAME);
if (isAppInstalled == true)
{
appsNeedAttention = true;
msg += APPLICATION_NAME + " is still installed.";
}
counter2++;
}
catch (Exception ex)
{
msg += ex.Message;
}
}
if (blah.Checked == true)
{
filename = "blah.txt";
}
else if (blah2.Checked == true)
{
filename = "blah2.txt";
}
if (counter2 == 0 && File.Exists(filename) == true)
{
msg = "There are no programs listed in the file.";
}
if (msg != "")
{
MessageBox.Show(msg, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
Try to change this part :
if (p_name.Equals(displayName, StringComparison.OrdinalIgnoreCase) == true)
{
return true;
}
To this :
//check null to avoid error
if (!string.IsNullOrEmpty(displayName))
{
//convert both string to lower case to ignore case difference
//and use contains to match partially
if (displayName.ToLower().Contains(p_name.ToLower()))
{
return true;
}
}
I have a master account file having more than 300000 records. This file is having Office, FA, UUID fields along with other fields. We have a webservice which retuns currently enrolled offices for pilot.
I need to generate a output file with unique UUIDs from master account file which are part of pilot. The below is my code.
public class Job
{
static Dictionary<string, string> UUIDOfficeFA = new Dictionary<string, string>();
static Dictionary<string, string> UUIDs = new Dictionary<string, string>();
static string PilotOfficeList = string.Empty;
/// <summary>
///
/// </summary>
public void RunJob()
{
try
{
DirectoryInfo directoryInfo = new DirectoryInfo(ConfigurationSettings.AppSettings["AccountFileFolder"]);
if (directoryInfo != null || directoryInfo.Exists == false)
{
FileInfo[] files = directoryInfo.GetFiles();
DateTime lastWrite = DateTime.MinValue;
FileInfo lastWritenFile = null;
foreach (FileInfo file in files)
{
if (file.LastWriteTime > lastWrite)
{
lastWrite = file.LastWriteTime;
lastWritenFile = file;
}
}
if (lastWritenFile != null)
{
if (RetrieveUUIDs(lastWritenFile))
{
WriteFile();
}
}
else
{
throw new Exception("No matching account file found for processing");
}
}
}
catch (Exception ex)
{
throw ex;
}
}
static void WriteFile()
{
try
{
string FileName = "Testfile_" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
string Path = ConfigurationSettings.AppSettings["TestFolder"] + #"\" + FileName;
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> kvp in UUIDs)
{
sb.AppendLine(kvp.Value);
}
using (StreamWriter writer = File.AppendText(Path))
{
writer.Write(sb.ToString());
writer.Flush();
}
}
catch (Exception ex)
{
throw ex;
}
}
static bool RetrieveUUIDs(FileInfo file)
{
try
{
using (StreamReader sr = file.OpenText())
{
string accountFileData = null;
accountFileData = sr.ReadToEnd();
string[] str = accountFileData.Trim().Split(new string[] { "\n" }, StringSplitOptions.None);
List<string> AccountInfo = new List<string>(str);
if (AccountInfo.Count > 0)
{
TestWebservice client = new TestWebservice();
GetBrancheListRequest request = new GetBrancheListRequest();
GetBrancheListResponse response =client.GetBrancheList(request);
if (response != null)
{
PilotOfficeList = response.GetBrancheListResult;
if (string.IsNullOrEmpty(PilotOfficeList))
{
throw new Exception("No branch is enrolled for pilot");
}
}
}
foreach (string accountInfo in AccountInfo)
{
RetrieveUUID(accountInfo);
}
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
private static void RetrieveUUID(string line)
{
try
{
string UUID = line.Substring(2, 50).Trim();
string Office = line.Substring(444, 3).Trim();
string FA = line.Substring(447, 3).Trim();
if (!string.IsNullOrEmpty(PilotOfficeList))
{
if (!string.IsNullOrEmpty(UUID) || !string.IsNullOrEmpty(Office))
{
if (PilotOfficeList.IndexOf(Office) > -1)
{
if (!UUIDOfficeFA.ContainsKey(UUID + Office + FA))
{
UUIDOfficeFA.Add(UUID + Office + FA, UUID + Office + FA);
if (!UUIDs.ContainsKey(UUID))
{
UUIDs.Add(UUID, UUID);
}
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
The issue is when this program runs the CPU utilisation goes to 100%. Although entire job completes within 2 minutes but i can't move this on server beacuse it might cause issue for other apps. Please suggest how i can optimize this so that CPU doesn't goes to 100%.
Thank you so much for your help in prior.
Note- It appears that following are few major CPU utilization points
1-
accountFileData = sr.ReadToEnd();
2-
string[] str = accountFileData.Trim().Split(new string[] { "\n" }, StringSplitOptions.None);
3-
foreach (string accountInfo in AccountInfo)
{
RetrieveUUID(accountInfo);
}
I am running a loop in C# that reads a file and make updates to the MySQL database with MySQL ODBC 5.1 driver in a Windows 8 64-bit environment.
The operations is simple
Count +1
See if file exists
Load XML file(XDocument)
Fetch data from XDocument
Open ODBCConnection
Run a couple of Stored Procedures against the MySQL database to store data
Close ODBCConnection
The problem is that after a while it will hang on for example a OdbcCommand.ExecuteNonQuery. It is not always the same SP that it will hang on?
This is a real problem, I need to loop 60 000 files but it only last around 1000 at a time.
Edit 1:
The problem seemse to accure here hever time :
public bool addPublisherToGame(int inPublisherId, int inGameId)
{
string sqlStr;
OdbcCommand commandObj;
try
{
sqlStr = "INSERT INTO games_publisher_binder (gameId, publisherId) VALUE(?,?)";
commandObj = new OdbcCommand(sqlStr, mainConnection);
commandObj.Parameters.Add("#gameId", OdbcType.Int).Value = inGameId;
commandObj.Parameters.Add("#publisherId", OdbcType.Int).Value = inPublisherId;
if (Convert.ToInt32(executeNonQuery(commandObj)) > 0)
return true;
else
return false;
}
catch (Exception ex)
{
throw (loggErrorMessage(this.ToString(), "addPublisherToGame", ex, -1, "", ""));
}
finally
{
}
}
protected object executeNonQuery(OdbcCommand inCommandObj)
{
try
{
//FileStream file = new FileStream("d:\\test.txt", FileMode.Append, FileAccess.Write);
//System.IO.StreamWriter stream = new System.IO.StreamWriter(file);
//stream.WriteLine(DateTime.Now.ToString() + " - " + inCommandObj.CommandText);
//stream.Close();
//file.Close();
//mainConnection.Open();
return inCommandObj.ExecuteNonQuery();
}
catch (Exception ex)
{
throw (ex);
}
}
I can see that the in parameters is correct
The open and close of the connection is done in a top method for ever loop (with finally).
Edit 2:
This is the method that will extract the information and save to database :
public Boolean addBoardgameToDatabase(XElement boardgame, GameFactory gameFactory)
{
int incomingGameId = -1;
XElement tmpElement;
string primaryName = string.Empty;
List<string> names = new List<string>();
GameStorage externalGameStorage;
int retry = 3;
try
{
if (boardgame.FirstAttribute != null &&
boardgame.FirstAttribute.Value != null)
{
while (retry > -1)
{
try
{
incomingGameId = int.Parse(boardgame.FirstAttribute.Value);
#region Find primary name
tmpElement = boardgame.Elements("name").Where(c => c.Attribute("primary") != null).FirstOrDefault(a => a.Attribute("primary").Value.Equals("true"));
if (tmpElement != null)
primaryName = tmpElement.Value;
else
return false;
#endregion
externalGameStorage = new GameStorage(incomingGameId,
primaryName,
string.Empty,
getDateTime("1/1/" + boardgame.Element("yearpublished").Value),
getInteger(boardgame.Element("minplayers").Value),
getInteger(boardgame.Element("maxplayers").Value),
boardgame.Element("playingtime").Value,
0, 0, false);
gameFactory.updateGame(externalGameStorage);
gameFactory.updateGameGrade(incomingGameId);
gameFactory.removeDesignersFromGame(externalGameStorage.id);
foreach (XElement designer in boardgame.Elements("boardgamedesigner"))
{
gameFactory.updateDesigner(int.Parse(designer.FirstAttribute.Value), designer.Value);
gameFactory.addDesignerToGame(int.Parse(designer.FirstAttribute.Value), externalGameStorage.id);
}
gameFactory.removePublishersFromGame(externalGameStorage.id);
foreach (XElement publisher in boardgame.Elements("boardgamepublisher"))
{
gameFactory.updatePublisher(int.Parse(publisher.FirstAttribute.Value), publisher.Value, string.Empty);
gameFactory.addPublisherToGame(int.Parse(publisher.FirstAttribute.Value), externalGameStorage.id);
}
foreach (XElement element in boardgame.Elements("name").Where(c => c.Attribute("primary") == null))
names.Add(element.Value);
gameFactory.removeGameNames(incomingGameId);
foreach (string name in names)
if (name != null && name.Length > 0)
gameFactory.addGameName(incomingGameId, name);
return true;
}
catch (Exception)
{
retry--;
if (retry < 0)
return false;
}
}
}
return false;
}
catch (Exception ex)
{
throw (new Exception(this.ToString() + ".addBoardgameToDatabase : " + ex.Message, ex));
}
}
And then we got one step higher, the method that will trigger addBoardgameToDatabase :
private void StartThreadToHandleXmlFile(int gameId)
{
FileInfo fileInfo;
XDocument xmlDoc;
Boolean gameAdded = false;
GameFactory gameFactory = new GameFactory();
try
{
fileInfo = new FileInfo(_directory + "\\" + gameId.ToString() + ".xml");
if (fileInfo.Exists)
{
xmlDoc = XDocument.Load(fileInfo.FullName);
if (addBoardgameToDatabase(xmlDoc.Element("boardgames").Element("boardgame"), gameFactory))
{
gameAdded = true;
fileInfo.Delete();
}
else
return;
}
if (!gameAdded)
{
gameFactory.InactivateGame(gameId);
fileInfo.Delete();
}
}
catch (Exception)
{ throw; }
finally
{
if(gameFactory != null)
gameFactory.CloseConnection();
}
}
And then finally the top level :
public void UpdateGames(string directory)
{
DirectoryInfo dirInfo;
FileInfo fileInfo;
Thread thread;
int gameIdToStartOn = 1;
dirInfo = new DirectoryInfo(directory);
if(dirInfo.Exists)
{
_directory = directory;
fileInfo = dirInfo.GetFiles("*.xml").OrderBy(c=> int.Parse(c.Name.Replace(".xml",""))).FirstOrDefault();
gameIdToStartOn = int.Parse(fileInfo.Name.Replace(".xml", ""));
for (int gameId = gameIdToStartOn; gameId < 500000; gameId++)
{
try
{ StartThreadToHandleXmlFile(gameId); }
catch(Exception){}
}
}
}
Use SQL connection pooling by adding "Pooling=true" to your connectionstring.
Make sure you properly close the connection AND the file.
You can create one large query and execute it only once, I think it is a lot faster then 60.000 loose queries!
Can you show a bit of your code?
I would like to know if there's a way to list the SQL Server instances installed on the local computer.
SqlDataSourceEnumerator and EnumAvailableSqlServers don't do the trick as I don't need the instances that are over the local network.
Direct access to Windows Registry isn't the recommended solution by MS, because they can change keys/paths. But I agree that SmoApplication.EnumAvailableSqlServers() and SqlDataSourceEnumerator.Instance fails providing instances on 64-bit platforms.
Getting data from Windows Registry, keep in mind the difference in Registry access between x86 and x64 platforms. 64-bit edition of Windows stores data in different parts of system registry and combines them into views. So using RegistryView is essential.
using Microsoft.Win32;
RegistryView registryView = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
using (RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
{
RegistryKey instanceKey = hklm.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL", false);
if (instanceKey != null)
{
foreach (var instanceName in instanceKey.GetValueNames())
{
Console.WriteLine(Environment.MachineName + #"\" + instanceName);
}
}
}
If you are looking for 32-bit instances on a 64-bit OS (pretty weird, but possible), you will need to look:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server
You could call EnumAvailableSQlServers with a localOnly = True
public static DataTable EnumAvailableSqlServers(bool localOnly)
See MSDN docs for EnumAvailableSqlServers
SqlDataSourceEnumerator instance = SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();
foreach (System.Data.DataRow row in table.Rows)
{
if (row["ServerName"] != DBNull.Value && Environment.MachineName.Equals(row["ServerName"].ToString()))
{
string item = string.Empty;
item = row["ServerName"].ToString();
if(row["InstanceName"] != DBNull.Value || !string.IsNullOrEmpty(Convert.ToString(row["InstanceName"]).Trim()))
{
item += #"\" + Convert.ToString(row["InstanceName"]).Trim();
}
listview1.Items.Add(item);
}
}
you can use registry to get sql server instance name in local system
private void LoadRegKey()
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names");
foreach (string sk in key.GetSubKeyNames())
{
RegistryKey rkey = key.OpenSubKey(sk);
foreach (string s in rkey.GetValueNames())
{
MessageBox.Show("Sql instance name:"+s);
}
}
}
Combined several methods:
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Smo.Wmi;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using Microsoft.Win32;
namespace SqlServerEnumerator
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, Func<List<string>>> methods = new Dictionary<string, Func<List<string>>>
{
{"CallSqlBrowser", GetLocalSqlServerInstancesByCallingSqlBrowser},
{"CallSqlWmi32", GetLocalSqlServerInstancesByCallingSqlWmi32},
{"CallSqlWmi64", GetLocalSqlServerInstancesByCallingSqlWmi64},
{"ReadRegInstalledInstances", GetLocalSqlServerInstancesByReadingRegInstalledInstances},
{"ReadRegInstanceNames", GetLocalSqlServerInstancesByReadingRegInstanceNames},
{"CallSqlCmd", GetLocalSqlServerInstancesByCallingSqlCmd},
};
Dictionary<string, List<string>> dictionary = methods
.AsParallel()
.ToDictionary(v => v.Key, v => v.Value().OrderBy(n => n, StringComparer.OrdinalIgnoreCase).ToList());
foreach (KeyValuePair<string, List<string>> pair in dictionary)
{
Console.WriteLine(string.Format("~~{0}~~", pair.Key));
pair.Value.ForEach(v => Console.WriteLine(" " + v));
}
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
private static List<string> GetLocalSqlServerInstancesByCallingSqlBrowser()
{
DataTable dt = SmoApplication.EnumAvailableSqlServers(true);
return dt.Rows.Cast<DataRow>()
.Select(v => v.Field<string>("Name"))
.ToList();
}
private static List<string> GetLocalSqlServerInstancesByCallingSqlWmi32()
{
return LocalSqlServerInstancesByCallingSqlWmi(ProviderArchitecture.Use32bit);
}
private static List<string> GetLocalSqlServerInstancesByCallingSqlWmi64()
{
return LocalSqlServerInstancesByCallingSqlWmi(ProviderArchitecture.Use64bit);
}
private static List<string> LocalSqlServerInstancesByCallingSqlWmi(ProviderArchitecture providerArchitecture)
{
try
{
ManagedComputer managedComputer32 = new ManagedComputer();
managedComputer32.ConnectionSettings.ProviderArchitecture = providerArchitecture;
const string defaultSqlInstanceName = "MSSQLSERVER";
return managedComputer32.ServerInstances.Cast<ServerInstance>()
.Select(v =>
(string.IsNullOrEmpty(v.Name) || string.Equals(v.Name, defaultSqlInstanceName, StringComparison.OrdinalIgnoreCase)) ?
v.Parent.Name : string.Format("{0}\\{1}", v.Parent.Name, v.Name))
.OrderBy(v => v, StringComparer.OrdinalIgnoreCase)
.ToList();
}
catch (SmoException ex)
{
Console.WriteLine(ex.Message);
return new List<string>();
}
catch (Exception ex)
{
Console.WriteLine(ex);
return new List<string>();
}
}
private static List<string> GetLocalSqlServerInstancesByReadingRegInstalledInstances()
{
try
{
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\InstalledInstances
string[] instances = null;
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server"))
{
if (rk != null)
{
instances = (string[])rk.GetValue("InstalledInstances");
}
instances = instances ?? new string[] { };
}
return GetLocalSqlServerInstances(instances);
}
catch (Exception ex)
{
Console.WriteLine(ex);
return new List<string>();
}
}
private static List<string> GetLocalSqlServerInstancesByReadingRegInstanceNames()
{
try
{
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL
string[] instances = null;
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL"))
{
if (rk != null)
{
instances = rk.GetValueNames();
}
instances = instances ?? new string[] { };
}
return GetLocalSqlServerInstances(instances);
}
catch (Exception ex)
{
Console.WriteLine(ex);
return new List<string>();
}
}
private static List<string> GetLocalSqlServerInstances(string[] instanceNames)
{
string machineName = Environment.MachineName;
const string defaultSqlInstanceName = "MSSQLSERVER";
return instanceNames
.Select(v =>
(string.IsNullOrEmpty(v) || string.Equals(v, defaultSqlInstanceName, StringComparison.OrdinalIgnoreCase)) ?
machineName : string.Format("{0}\\{1}", machineName, v))
.ToList();
}
private static List<string> GetLocalSqlServerInstancesByCallingSqlCmd()
{
try
{
// SQLCMD -L
int exitCode;
string output;
CaptureConsoleAppOutput("SQLCMD.exe", "-L", 200, out exitCode, out output);
if (exitCode == 0)
{
string machineName = Environment.MachineName;
return output.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries)
.Select(v => v.Trim())
.Where(v => !string.IsNullOrEmpty(v))
.Where(v => string.Equals(v, "(local)", StringComparison.Ordinal) || v.StartsWith(machineName, StringComparison.OrdinalIgnoreCase))
.Select(v => string.Equals(v, "(local)", StringComparison.Ordinal) ? machineName : v)
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
}
return new List<string>();
}
catch (Exception ex)
{
Console.WriteLine(ex);
return new List<string>();
}
}
private static void CaptureConsoleAppOutput(string exeName, string arguments, int timeoutMilliseconds, out int exitCode, out string output)
{
using (Process process = new Process())
{
process.StartInfo.FileName = exeName;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
output = process.StandardOutput.ReadToEnd();
bool exited = process.WaitForExit(timeoutMilliseconds);
if (exited)
{
exitCode = process.ExitCode;
}
else
{
exitCode = -1;
}
}
}
}
}
public static string SetServer()
{
string serverName = #".\SQLEXPRESS";
var serverNameList = SqlHelper.ListLocalSqlInstances();
if (serverNameList != null)
{
foreach (var item in serverNameList)
serverName = #"" + item;
}
return serverName;
}
To get local server names