How do I detect whether MySQL is installed? - c#

Without the help of the registry, how do I know whether MySQL is installed or not? I am trying to determine this on a Windows machine through C#.
I have found a solution that involves querying the registry, but I don't want to rely on this. Is there any function in C# for determining the currently installed software?

You can do this through WMI: the class you need is Win32_Product.
It's really easy in Powershell:
Get-WmiObject -Class Win32_Product
will get the list of installed products, which you can then filter.
In C#, try the System.Management namespace:
public bool CheckForMySQLServer()
{
string query = "SELECT Name FROM Win32_Product WHERE Name LIKE '%MySQL Server%'";
var searcher = new ManagementObjectSearcher(query);
var collection = searcher.Get();
return collection.Count > 0;
}
Note that this is hideously slow - takes over a minute on my PC - but you can get hold of the version number string if you need (see the GetText() method on the collection items).

Assuming that you also need to access MySQL (a.o.t. just knowing about its presence) you could
(Optional) load GAC copy of MySQL connector via reflection in a try-catch block, if that fails
load local copy of MySQL connector
Try to connect to localhost with bad username/password
Check error code. If this is "access denied" you have MySQL

Check MySQL installation registry key:
bool IsMySqlInstalled()
{
return Registry.LocalMachine.OpenSubKey(#"SOFTWARE\MySQL AB") != null;
}
MySQL details on what key is created can be found here, under 'Changes to the Registry' section:
The MySQL Installation Wizard creates one Windows registry key in a
typical install situation, located in
HKEY_LOCAL_MACHINE\SOFTWARE\MySQL AB.

Related

C# Executing a query and getting data out of an Access Database (accdb) without using ACE.OLEDB

I'm writing a WPF application.
Trying to use the normal method of getting a connection returns an error similar to: "The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine."
ACE.OLEDB has never been installed on this machine so this error makes sense.
I'm trying to create this application in a way so that our users won't need to contact IT to have the application installed. Getting IT involved is a no go situation and the project will be abandoned.
Another team has an Access database (accdb) that I want my application to extract information (only read, no insert or update). I talked to the team and they won't convert this database back to an earlier version (mdb).
After my research I assume that installing ACE.OLEDB without using Admin privileges is impossible. Because of this and my application requirement of not requiring admin privileges I need to start looking for "Mutant"/Dirty solutions that don't involve ACE.OLEDB.
I tried using power-shell but I'm getting the same problems as I had with C# (requires IT to install ACE.OLEDB).
I have two potential solutions. One write a VBA script that opens up the database and dumps a query result into a file. My C# application would call this VB script and then parse the created file.
The second option is to create a new Access process using Process.Start(fullFilePath) and somehow pass the command to execute a query and somehow pass the results back to the executing application (either via a method return or first to a file).
How would you get the data out?
Is there a way for C# to duplicate the DB file and convert it from (accdb -> mdb)?
This is the second question I ask that is very similar.
C# Connecting to Access DB with no install
The difference between the two (to prevent this is a duplicate question) is that in the previous question I was looking for ways to install ACE.OLEDB without admin privileges while here I'm just looking for any other work around.
Found a workaround. It uses Microsoft.Office.Interop.Access found in NuGet.
var accApp = new Microsoft.Office.Interop.Access.Application();
accApp.OpenCurrentDatabase(#tests.DatabasePath);
Microsoft.Office.Interop.Access.Dao.Database cdb = accApp.CurrentDb();
Microsoft.Office.Interop.Access.Dao.Recordset rst =
cdb.OpenRecordset(
"SELECT * FROM Users",
Microsoft.Office.Interop.Access.Dao.RecordsetTypeEnum.dbOpenSnapshot);
while (!rst.EOF)
{
Console.WriteLine(rst.Fields["username"].Value);
rst.MoveNext();
}
rst.Close();
accApp.CloseCurrentDatabase();
accApp.Quit();

Informix connection string field descriptions and values to be used

I am writing a test application in .net using c# to connect to IBM's Informix database.
So far what i did is, i installed Informix client sdk v4.10 in my machine. After that i wrote a piece of code referring from here and here. In my code i have a reference to IBM.Data.Informix.dll which is referred from installed path of Informix client sdk's bin folder netf40.
When i run a test application, i am getting below error while trying to opening up an connection,
ERROR [HY000] [Informix .NET provider][Informix]System error occurred
in network function.
i assume this error is due to connection string field not been supplied properly, i referred https://www.connectionstrings.com/informix/ and tried using connection string like informix with ODBC driver and informix .net provider mentioned in above link but no use, i am also having difficulty in understanding from where to get values for each connection string fields like protocol, port, host-name , server-name and service name.
To find values of above fields, i tried looking for SQLHOSTS key in registry entries under HKEY_LOCAL_MACHINE\SOFTWARE\INFORMIX\ unfortunately it wasn't there! and also tried running setnet32.exe from client sdk's bin folder and i could see below screen with only protocol info!.
It would be really helpful if anyone can help me.
This is a very, very difficult question to answer blind. :-)
setnet32.exe will not know the information you are looking for, you need to provide this information to setnet32.exe.
The first question to ask is: is your database running on Unix or Linux? If it is, then by logging in to the database server as user "informix" and running the command
cat $INFORMIXDIR/etc/sqlhosts
If you're on Windows, then login to the Windows server and from a command prompt, run
TYPE %INFORMIXDIR%\etc\sqlhosts
This should give you a file with potentially a bunch of information, you're looking for lines that are not comments and have at least 4 columns. This is my sqlhosts file on a Docker I'm testing:
$ cat $INFORMIXDIR/etc/sqlhosts
############################################################
### DO NOT MODIFY THIS COMMENT SECTION
### HOST NAME = 7edf3045c382
############################################################
informix onsoctcp 7edf3045c382 9088
informix_dr drsoctcp 7edf3045c382 9089
The last two lines are the guts of the file.
Column 1 is the name of the INFORMIXSERVER or an alias (IBM Informix Server in setnet32.exe)
Column 2 is the protocol name (Protocolname in setnet32.exe)
Column 3 is the host name (HostName in setnet32.exe)
Column 4 is the port number or name (Service name in setnet32.exe)
If column 4 is a name and you're on Unix or Linux, then search for the port name in /etc/services on your Unix or Linux server. If you're on Windows, then it will be in %windir%\system32\drivers\etc\services (or similar).
Once you have that, you can then run the command
dbaccess
Choose the Database option, followed by the Select option. This should present you with a list of databases, roughly like:
SELECT DATABASE >>
Select a database with the Arrow Keys, or enter a name, then press Return.
------------------------------------------------ Press CTRL-W for Help --------
backbone#informix wallet#informix
cust#informix
retail#informix
sports#informix
sysadmin#informix
sysha#informix
sysmaster#informix
sysuser#informix
sysutils#informix
In general, databases called "sys" are reserved for Informix administration, and may not be actual databases, although you can query them with SELECTs, you probably won't be able to (and really shouldn't!!) INSERT, UPDATE or DELETE or use DDL.
In my database list above, all the sys* databases are Informix administration "databases". Database names are shown in my example in "databasename#informixservername" format.
You should now have all the information you need to access your database.

Unable to Access Embedded Firebird Database Server with .Net Client

Unable to Access Embedded Firebird Database Server with .Net Client
I aim to develop a program which uses the Embedded Firebird Server but face errors when trying to make a connection using the .Net client. I have followed the advice from multiple threads on making it work, but I can’t figure it out. I’ve tried changing the connection string and files but keep getting the same errors.
Here is a detailed explanation of my research and everything I have tried so far:
How to connect and use Firebird db embedded server with Visual C# 2010
I download the files specified in the links, followed the steps and ran the code and got the same error message as did the original poster:
FirebirdSql.Data.FirebirdClient.FbException
Message=Unable to complete network request to host "127.0.0.1".
Using "localhost" in place of the IP generates the same error.
The accepted answer is to make sure all the .dll and config files are copied to my project files (directory with the code ) and the output directory (bin/debug), which I have done. I copied over every file in the zip folder. Additionally #Robin Van Persi states to not use the “compact .Net data provider”, how do I know if I am using this? I downloaded the file from the link in the question.
Another answer contributed by #PlageMan is to add ServerType=1; to the connection string and remove the DataSource and Port attributes which produces these errors:
FbConnection con = new FbConnection("User=SYSDBA;Password=masterkey;Database=TEST.FDB;Dialect=3;Charset=UTF8;ServerType=1;");
System.NotSupportedException Message=Specified server type is not correct.
FbConnection con = new FbConnection("User=SYSDBA;Password=masterkey;Database=TEST.FDB;Dialect=3;Charset=UTF8;");
System.ArgumentException
Message=An invalid connection string argument has been supplied or a required connection string argument has not been supplied.
The last answer by #Toastgeraet adds to rename the fbembed.dll to either fbclient.dll or gds32.dll. I’ve tried it all three ways, no change. In fact http://www.firebirdsql.org/en/firebird-net-provider-faq/ says fbembded.dll but that didn’t work either.
How to solve connection error in c# while using firebird embeded database?
Has the same advice on renaming the fbembed.dll to fbclient.dll which didn’t work for the original poster either.
The accepted answer ServerType=1 in the connection string, but a comment under #cincura.net answer gave me a new possibility to investigate; processor architecture. Unfortunately, switching between 64bt and 32bit versions didn’t make any difference.
I thought switching to the 32bit version might have been the answer since I'm using Visual Studios Express.
Error in using Embeded Firebird
The last comment in this thread is another person saying that changing to 32bit didn’t solve the problem either.
Trying to use the firebird embedded server - Specified server type is not correct
I went back to looking up information on the ServerType because I have seen it as 1 and 0 and found this post. #Nigel answer is to update to the latest version of the .Net provider. Unfortunately, I can’t figure out how to use the newest version on the Firebird website (4.5.1.0) because it lacks FirebirdSql namespace from the examples. Additionally, Visual Studios gives me some warning about the wrong version of .Net being targeted when I import it.
What am I doing wrong? Do I need to use a different connection string or new version of Firebird/ .Net provider? Am I missing something else?
I realize that this question may be considered a duplicate, but none of the answers I have found so far have solved my issue. Additionally, the previous StackOverflow Q/A’s which I have cited above are all years old so I’m hoping someone may have new information to share.
I just created a very basic program to test Firebird embedded from C#. You need to add the latest FirebirdSql.Data.FirebirdClient nuget package (4.5.1.0), and drop the entire contents of a Firebird embedded zip kit into the same folder as the .exe.
Note that you need to match the bitness of the application:
x86 (32 bit): Firebird-2.5.3.26778-0_Win32_embed.zip
x64 (64 bit): Firebird-2.5.3.26778-0_x64_embed.zip
AnyCPU seems to be rather tricky. When I compiled the executable as AnyCPU and ran it on a 64 bit machine, it gave a BadImageFormatException when combined with Firebird Embedded 64 bit, but worked with Firebird Embedded 32 bit; which is the opposite of what I expected.
class Program
{
private const string DefaultDatabase = #"D:\data\db\employee.fdb";
static void Main(string[] args)
{
string database = args.Length > 0 ? args[0] : DefaultDatabase;
var test = new TestEmbedded(database);
test.RunTestQuery();
Console.ReadLine();
}
}
class TestEmbedded
{
private readonly string connectionString;
public TestEmbedded(string database)
{
var connectionStringBuilder = new FbConnectionStringBuilder();
connectionStringBuilder.Database = database;
connectionStringBuilder.ServerType = FbServerType.Embedded;
connectionStringBuilder.UserID = "sysdba";
connectionString = connectionStringBuilder.ToString();
Console.WriteLine(connectionString);
}
internal void RunTestQuery()
{
using (var connection = new FbConnection(connectionString))
using (var command = new FbCommand("select 'success' from RDB$DATABASE", connection))
{
Console.WriteLine("Connecting...");
if (connection.State == System.Data.ConnectionState.Closed)
{
connection.Open();
}
Console.WriteLine("Executing query");
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
Console.WriteLine(reader.GetString(0));
}
}
}
}
}
The connection string generated by this program is:
initial catalog=D:\data\db\employee.fdb;server type=Embedded;user id=sysdba
This seems to be the minimum required to connect. Note that although Firebird embedded on windows doesn't perform any authentication, providing user id is required, otherwise the trusted authentication is triggered which doesn't work with Firebird embedded.
The only way that works for me: setting the client path in the connection string.
<add name="MyEmbeddedDb" connectionString="user=SYSDBA;Password=masterkey;Database=|DataDirectory|MyDb.fdb;DataSource=localhost;Port=3050;Dialect=3;Charset=NONE;ServerType=1;client library=C:\firebird\fbembed.dll" providerName="FirebirdSql.Data.FirebirdClient" />
C:\Firebird is a folder I've extracted the entire downloaded zip file (Firebird-2.5.4.26856-0_Win32_embed.zip)

Access denied for user 'root'#'localhost' (using password: YES) in Visual Studio

Kindly bear with me. I am a Microsoft SQL Server person with loads of Visual Studio experience, but I need to get something done using a MySQL database.
I am trying to create a little tool here that will allow our developers to quickly update database records, and I am using Visual Studio to create a small Windows Form to do this.
In a Microsoft SQL Server connection string, I could write something like this:
Server=myServerAddress;Database=myDataBase;User Id=username;Password=password;
In a MySQL connection string, there appear to be multiple other options, but the first one looks basically the same:
Server=myServerAddress;Database=myDataBase;Uid=username;Pwd=password;
When I attempt to open the MySQL connection from my PC, I get the exception listed in the title (actually, it shows the Uid value and the IP Address of my PC instead of localhost, but I am hoping more people will recognize the error easier this way):
public static void MySQLi_Connect() {
m_err = null;
var str = Properties.Settings.Default.ConnStr;
try {
m_conn = new MySqlConnection(Properties.Settings.Default.ConnStr);
m_conn.Open();
} catch (MySqlException err) {
ErrorLog("MySQLi_Connect", err);
}
}
I did a search, and it seems that the Uid on MySQL needs to be granted access from the specific IP Address that the connection is being made from.
Further, I found this on the mysql.com doc pages:
If you do not know the IP address or host name of the machine from which you are connecting, you should put a row with '%' as the Host column value in the user table. After trying to connect from the client machine, use a SELECT USER() query to see how you really did connect. Then change the '%' in the user table row to the actual host name that shows up in the log. Otherwise, your system is left insecure because it permits connections from any host for the given user name.
A few things:
It looks like I can connect to MySQL by using a % setting in the Uid jp2code, but MySQL says I need to change that back right away to remove system vulnerability.
Microsoft SQL Server did not seem to require this - or, if it did, I simply never was slapped in the face with this vulnerability issue like MySQL is doing.
Now, I ask:
If this is going to be a tool used by different developers on different PCs, is it common practice to turn the blind eye to this horrendous system vulnerability?
Is this not really as big of a concern as MySQL is making it appear?
What is the best way to continue with a Windows Forms application that needs to connect from various locations? Obviously, I do not want to continuously be adding more entries for a particular application every time another developer wants to use the tool or someone tries to run it from a different PC.
You can configure the security of your MySQL server as strong as you like, usually you dont connect users but applications. So if you have your root user without password in production environment is your fault. Usually developers have access to development environment, so this is not a big deal.
Of course try to have as many users as roles you need, for your example I think one user is enough. In production use a secure config file for save a secure password and set you mysqlserver restricted.
I was having the same issue and I found out that the password wasn't correct.
GO to your sql command line and type the code below:
mydb in the line below is the name of the database you are working on.
passwd in the line has to match the password you have in c# code so in your case "password"
grant all privileges on mydb.* to myuser#localhost identified by 'passwd';
Like OP says you can wildcard the hostname portion. I used this on our dev-server (not recommended for production servers):
update mysql.user set host = '%' where host='localhost';
Then I had to restart the server to make MySQL use it (propably I could just have restarted the MySQL service).

How can I use WMI to find out the installed Exchange Version using C#?

I would like to be able to query the Exchange version installed on our user's server. I understand that this can be done using WMI, but I'm having a hard time finding a simple explanation using Google. Any advice?
This should get you started:
string condition = "Vendor LIKE 'Microsoft%' AND Name = 'Exchange'";
string[] selectedProperties = new string[] { "Version" };
SelectQuery query = new SelectQuery("Win32_Product", condition, selectedProperties);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
using (ManagementObjectCollection products = searcher.Get())
foreach (ManagementObject product in products)
{
string version = (string) product["Version"];
// Do something with version...
}
That searches for instances of the Win32_Product class where the Vendor property begins with "Microsoft" and the Name property is "Exchange", and retrieves the Version property. I don't have access to an installation of Exchange to know what those values will actually be. Even better would be if you can determine what the ProductID property would be for Exchange so you can filter just based on that.
Note that not all installed applications are returned by Win32_Product (it seems to be mostly Microsoft applications and those with Windows Installer installers). So, for all I know Exchange is not one of these applications!
I also have the same question: Exchange (server) on user's computer?
btw, here you can find a good sample source with explanations of how to retrieve list of installed applications on (any) windows pc, using WMI.
The idea behind this is using "SELECT * FROM Win32_Product" query from "\root\cimv2" to select list of applications.
each application item (implemented class) has it's own 'IdentifyingNumber', 'Description', 'Version', etc. which help you find your answer.

Categories