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)
Related
I have successfully established a connection to a remote Linux server using the SSH.NET package with the following code (I am using a ShellStream because I have to use sudo su):
using (var client = new SshClient(server, username, password))
{
client.Connect();
List<string> commands = new List<string>();
commands.Add("sudo su - user");
commands.Add("vi test.properties");
ShellStream shellStream = client.CreateShellStream("xterm", 80, 24, 800, 600, 1024);
// Execute commands under root account
foreach (string command in commands) {
WriteStream(command, shellStream);
}
client.Disconnect();
}
private static void WriteStream(string cmd, ShellStream stream)
{
stream.WriteLine(cmd + "; echo this-is-the-end");
while (stream.Length == 0)
Thread.Sleep(500);
}
I am trying to edit the test.properties file that is in the remote Linux server using a C# function that I created.
My code (using C# in Visual Studio) that is used to modify the text file is uses System.IO.File.ReadAllText, but it does not recognize the path of the remote server, for example:
The text file in the Linux server is in this location: /home/user/test.properties, so I am using this in my code:
System.IO.File.ReadAllText("/home/user/test.properties")
I am getting the following error:
Could not find a part of the path 'C:\home\user\test.properties'
For some reason it tries to look in my local file system instead of the remote server.
Is there a different approach I should be taking?
Thanks in advance!
In general, to modify remote files, use SFTP. In SSH.NET that's what SftpClient is for.
Though as you seem to need to use elevated privileges (su) – an important factor that your question title fails to mention – it's way more difficult. The right solution is to avoid the need for su. See somewhat related:
Allowing automatic command execution as root on Linux using SSH.
Another option would be to try to execute the SFTP server under su. Though that would require modification of SSH.NET code. See related Java question:
Using JSch to SFTP when one must also switch user
If you want to keep your current shell approach with su, you are stuck with simulating shell commands. Note that connecting to SSH server won't make other .NET classes (like the File) magically be able to work with remote files (even if SFTP was possible, let only when it is not, due to the su requirement).
The easiest way to read remote file using shell is using the cat command:
cat /home/user/test.properties
Alright, so after finishing the task, this is what I did since asking the question here:
1.After your(#Martin Prikryl) response I've tried using a combination of SSH and WinSCP:
WinSCP to download the file.
.NET to modify the locally downloaded file.
WinSCP to upload the file(and deleting it from the local folder afterwards).
SSH to move the file to its appropriate location in the server.
I discarded this solution because it worked pretty well in the lower environment,
but in the production I had permissions issues so I couldn't even download it, let alone that it might be a security issue(its a sensitive file).
2.My next solution was using only SSH to simulate shell commands, as you previously mentioned, I was limited to that because I was stuck using sudo su.
I connected to the server with SSH and used the 'sed' command to only show lines that contain specific words(instead of using cat to get the whole file).
I then used my .NET code to pull the values that I needed for my GET operation
For the POST operation I used 'sed' again to replace lines.
I have a project in C# which is created in Visual Studio 2013. I want to create an installer using Install Shield free version. I created an installer and trying to run it on other computer but, when I run it and trying to log into program, I have problems about mysql database. Error message is:
Unhandled exception has occured in you application. If you click Continue, the application will ignore this error and attempt to continue. If you click Quit, the application will close immediately.
Cannot connect.
If I click on details button, I have a serie of errors which refers on Mysql. Example:
System.Exception: Cannot connect ---> MySql.Data.MySqlClient.MySqlException: Unable to connect to any of the specified MySQL hosts.
at MySql.Data.MySqlClient.NativeDriver.Open()
at MySql.Data.MySqlClient.Driver.Open()
at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
at MySql.Data.MySqlClient.MySqlPool.GetConnection()
at MySql.Data.MySqlClient.MySqlConnection.Open()
at simulator.ConnConfig.getConnection()
simulator is the name of the project. ConnConfig is a class where is the connection and getConnection() is a function from ConnConfig which return connection. II tried to install on another computer .NET Framework 4.5.2, SQL Server, but also didn't worked.
In my project, I use localhost server where I have a database with 2 tables. My question is, is there any possibility to add that localhost database to installer and use it on another computer? And what redistributables requires this operation? Also, I have installed on computer .NET Framework 4.5, Sql Server 2012..but when I try do add them in InstallShield via Redistributables, but it keeps saying that Needs to be downloaded. Why?
UPDATE
I have this Class where I make the conenction. But I receive error: Additional information: Illegal characters in path. at that line:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SQLite;
namespace simulator
{
class ConnConfig
{
private static string conn = "Data Source=c:\aplicatie.db;Version=3;Password=myPassword;";
public static SQLiteConnection connect = null;
private ConnConfig()
{
}
public static SQLiteConnection getConnection()
{
SQLiteConnection connect = null;
try
{
connect = new SQLiteConnection(conn);
connect.Open();// here I receive the error
return connect;
}
catch (SQLiteException e)
{
throw new Exception("Cannot connect", e);
}
}
}
}
UPDATE 3
In that class I make the connection to database. In the other forms I just use tables and their data. For connection to program, I use a login form which uses this class to getConnection(). I created that database by adding an ADO.NET in simulator project. And with that, it comes those 2 tables that I already have in localhost server. So, Is ok if I have to create another empty database with new tables, but where to include that code or how to use it, because I don't get how that script works..where should I put it?
If your database is going to be installed on each client and your tables are not massive you might want to look at something lighter like SQLite which doesn't need any installation just the dlls and is very fast and efficient and only runs when your program does.
As for for the Needs to be Downloaded issue, it seems you have not setup your prerequisite correctly, you an correct this by following the steps in this article
Adding InstallShield Prerequisites, Merge Modules, and Objects to Basic MSI and InstallScript MSI Projects
You might want to look into determining if MySQL is the right solution for you.
SQLite vs MySQL vs PostgreSQL: A Comparison Of Relational Database Management Systems
And to see the limitations of SQLite SQLite
Because honestly seems like overkill to install MySQL on every system. If you had one server with MySQL on the network, okay. But on every system seems like a bad idea.
As far as connecting to an SQLite database here is a List of Connection Strings for SQLite
See this topic on how to create Databases and tables Create SQLite Database and table
My guess is your program doesn't bundle up the database alongside the setup upon deployment. This may be due to the fact that you didn't mark your database as a Data File in the Project Files. Try this, right click on your project name in Solution Explorer and select Properties from Menu. From the horizontal tabs click on the Publish Tab. Under Install Mode and Settings click the Application Files button. A dialog box appears with all Application files. Set your database Publish Status to Data File from the drop down on the corresponding cell. This way your database will be bundled together with the setup upon publishing. Hope this helps.
You can access SQLite via ODBC.
Hi I have to connect to an Oracle Database( about which I know a little) using a windows application.
The windows application will not necessarily be in the same system.
I just needed the connection string.
So I Used Add connection functionality in Visual Studio 2014 to test the connection and get the string.
eedb is the SID which i read in stackoverflow question
Now using above, i was able to connect to the database using this functionality and even in my visual studio server explorer all the tables of the oracle database were showing but I needed to use the connection string in the windows application.
So I used following string:
DATA SOURCE=172.31.8.21:1521/eedb;USER ID=PDB_E_GND_R
I added password too to this string as
DATA SOURCE=172.31.8.21:1521/eedb;USER ID=PDB_E_GND_R;PASSWORD=123
when i run the application i get error.
System.Data.OracleClient.OracleException: ORA-01017: invalid username/password; logon denied.
So :
Why I am getting this error. Now some may mark this question as duplicate and even point out the answer can be found in issue stackoverflow question
Coz if this was the case I would have been unable to establish connection through add connection functionality of Visual Studio at all.
Please note: I added the reference: Oracle.DataAccess
And also for a programmer like me who has very little knowledge regarding the oracle.
How I can know which connection string I have to use for a particular oracle db.
Try the following connection string EZ connect does not seem to be so EZ
data source=(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 172.31.8.21)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = eedb)));USER ID=PDB_E_GND_R;PASSWORD=123
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.
I'm here for a trouble with SQL Server CE in a C# application.
This is a really simple question, at first I was trying to do an INSERT into a table, but it didn't do it, so I searched and the solution was to put the literal string to connect to the database.
try
{
cnTrupp.Open();
SqlCeCommand com = new SqlCeCommand("INSERT INTO tipo_venta(nombre) VALUES (#nombre)", cnTrupp);
com.Parameters.AddWithValue("#nombre", pNombre);
com.ExecuteNonQuery();
com.Dispose();
}
catch (SqlCeException e)
{
LogFile log = new LogFile(e.Message);
}
finally
{
cnTrupp.Close();
}
After that with the literal string, I was wondering, when I deploy the app, how I'm supposed to change that connection string? so it points to the actual database in the new computer
The comments on "Paul Sasik"'s post talk about the Data Source=|DataDirectory|\example.sdf entry in the app.config file of your application.
For the sake of completeness: This |DataDirectory| part is a macro that expands automatically to the folder where your application is running and should not be hardcoded. If you want to change the folder, you may use the following line in Program.cs:
AppDomain.CurrentDomain.SetData("DataDirectory", <New Folder>);
At least this is true for desktop applications. As mobile applications (in VS 2005 and 2008) don't support the same configuration mechanism, you have to create the connection string manually there.
Make use of the .NET app.config file. This is a VB article but will get you started.
.NET config files are fairly easy to work with but with information like a db connection, you might want to consider encrypting the string in the config file. Or at least the password. That is if security is a concern. Many times it's not. Especially on mobile devices which are inherently unsecure (at least in the WinCE world... up to CE5 v.6)