I have read a lot of information about this issue.
And there are many questions in SO for this , but the problem still remains and it is the following:
I have understand that this connection string is for the older versions of Office :
string oldCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ path + ";" + "Extended Properties='Excel 8.0;HDR=NO;IMEX=1;'";
and I know that there is this connection string for the newer versions of Office:
string nweCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
+ path + ";Extended Properties=Excel 12.0;";
However , when I use the connection string for the newer versions with the ACE , I have this error :
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
I have also read in other questions that I should install ACE first and the everything will work fine.
I do not have ACE driver installed neither the other computers that should use this Application, is there a way to read the Excel files using the JET for Office 2016 or 365 (everything above 2003).
I can not install the ACE in every of my clients in order to be able to work with my Application , it is not practical at all.
Is there a way to do this?
I had to solve the exact same problem many years ago. I added both connection strings to my configuration. When the application is used for the first time, I check with one ACE driver (since it is newer). If that fails, I will fallback to Jet. Save the working connectiion string in the AppConfig (you can save values to config too). So the next time you run the application, it will check the app config first and use that connection string on that machine.
Here are the steps I followed:
When application is launched/used for the first time on the machine try to get the working connection string from AppConfig.
Since it won't be available, you check with list of possible connection strings.
Start with ACE driver. Is successful, save it in the AppConfig.
If ACE failed, check with next driver (Jet). If this is successful, save this one as working connection string.
Next time when you launch the application, check the working connection string and proceed with it. That way you are not checking for both drivers again and again.
Note: When you update setting to AppConfig file they are not directly updated to original file. A copy of file is created for that user under C:\Users<UserName>.... When you try to load the values from AppConfig, these two are "merged" and used. This is automatically handled in C#.
Based on the above, if you ever have to reset the selection, you have to remove the config file in the user folder above and that should start the process from step 1 again.
Related
I connected an Access database (accdb) with C#-windows application project.
The "accdb" database is located in a folder in desktop. It works correctly on my computer but when i build a setup file and installed it on other computer the software didn't work. (i know the problem is that the database located in the folder) but i dont't know how to change the code that after installation on other computer, it can still connect to the database.
Does anyone know how should i solve this problem?
Here is the simple connection that i wrote:
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\aa\Test.accdb;Jet OLEDB:Database Password=123;");
It works correctly on my computer but when i build a setup file and installed it on other computer the software didn't work.
The primary reason for this is because that path doesn't exist on the other machine; you've hard-coded your path.
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\aa\Test.accdb;Jet OLEDB:Database Password=123;");
C:\Users\aa\Test.accdb this is the actual issue, you shouldn't hard code this value, instead you have two options I can think of.
Look for the file along side the application where it is being executed from (this requires the file to be inside the same directory the exe is in).
You could allow the end user to enter the location of that file, if it exist, save this path to use again when needed.
You can use either or I mention above and or do both of them, your choice. Below is a simple example using option one above.
using System.Reflection;
using System.IO;
public static string GetDBConnection()
{
try
{
string dbExecPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Test.accdb");
return $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={ dbExecPath };Jet OLEDB:Database Password=123;";
}
catch (Exception)
{
return string.Empty;
}
}
This get's the assemblies location (path) and combines it with your file name (db file). Then combine's that with your other connection string parts and return's the whole connection string.
Please Note: the namespaces that have to be used and the db file must be in the same directory that the exe is if going this route.
Now you can call it like this:
OleDbConnection con = new OleDbConnection(GetDBConnection());
You may want to assign the GetDBConnection() to a var and check if it's empty before constructing your connection, it may be empty.
I am creating a C# windows form application, the working can be summarized as users fills some form and data is saved in SQL database. Now the problem I am facing is that I have to deliver this as an executable file to someone. But the problem is database is creating issues as the connection string is not match with that computer. I know that if a distribute projects I can put connection string in app.config and every user can change it according to his/her machine. But i want to make it more convenient for the user not to change the connection string as i am only giving the executable file to client. as i have the connection string in my project is
String ConString = #"Data Source=(LocalDB)\v11.0; AttachDbFilename=D:\Users\khan\Desktop\MyApp\MyApp\Database1.mdf;Integrated Security=True";
So how to make it generic so that the client does not need to change the connections string. Kindly elp me out in this issue.I have searched a lot but still not done with it.
Try to use a Enviroment Variable instead of a fixed path in AttachDbFilename.
For example %APPDATA%\Database1.mdf.
I have narrowed done my problem to small sample where this issue can be easily produced.
Brief -
I am using embeded dll's of firebird for database connectivity i.e. fbembed.dll to connect to firebird databases.
In code, i have three connection strings like this (note additional attribute client library specified in third connection string) -
private const string connection1 = #"User=SYSDBA;Password=masterkey;Database=D:\DB1.fdb;ServerType=1;Charset=UTF8";
private const string connection2 = #"User=SYSDBA;Password=masterkey;Database=D:\DB2.fdb;ServerType=1;Charset=UTF8";
private const string connection3 = #"User=SYSDBA;Password=masterkey;Database=D:\DB2.fdb;ServerType=1;client library=D:\fbembed.dll;Charset=UTF8";
I have two buttons on UI and on first button click i have this code -
FbConnection fbConnection = new FbConnection(connection1);
fbConnection.Open();
On second button click i have this code -
FbConnection fbConnection = new FbConnection(connection3);
fbConnection.Open();
If i create connection with connection string specified as connection3, i am getting FbException "operating system directive CreateFile failed".
However, if i replace the connection string as connection2, it works fine.
Moreover, if i create connection with connection3 and then with connection1 no issue but in case i create connection with connection1 and then connection3, same fbexception coming.
Note, the database specified in connection2 and connection3 is same but only difference is of additional attribute client library.
Why this strange behaviour with embeded firebird. It all works fine in case i have firebird server installed on my system. But, i want to know the issue why it persists in embeded dll's of firebird?
Your issue is related to: http://tracker.firebirdsql.org/browse/CORE-2507
This is a bug in FB engine, fixed in 2.1.4 version.
The problem is that you are connecting to database with Firebird server and Firebird embeeded. The first one locks the database file for open with other proceses(i think you are using superserver).
Another option is that you are using two fbembed.dll from different locations.
This is rather funny but I fixed my Firebird 1.5 + Windows 7 problem!
Installed Firebird as application then ran fb application as admin and the batch file (gbak.exe -b -v -g) also as admin.
Got rid of:
**ERROR**:uavailable database
or
operating system directive CreateFile failed
I am having issues connecting to my sqlite database. The file is located in the application's folder. Here is the connection string
string path = "Data Source=MY.db";
I can get it to work if I use the absolute path, but it gives me a "table not found" error if I try to use a relative path. Any ideas?
You are opening up a different -- perhaps a new -- database that does not have said table. (Yes, SQLite will happily create a new database with the default connection settings.)
Make sure the correct database is opened. Remember, relative path is relative to the Current Working Directory, which is likely not that which is expected.
(The working directory is influenced from where, and how, the process is loaded. The working directory for a "Debug" session can be set under Project Settings / Debug / Start Options, for instance.)
Happy coding.
See also:
Make SQLite connection fail if database is missing? (deleted/moved)
Defining a working directory for executing a program (C#) (Shows how to set the current working directory to the directory containing the executing assembly.)
How do I get/set a winforms application's working directory?
Getting path relative to the current working directory?
This happened when you haven't saved the database and its table while using GUI Manager for SQLite .
Two solution;
1) Save your database and its table with CTR+S in GUI Manager
2) Or Simply Just close your GUI manager of SQlite and save all .
Important ! I am using GUI manger for SQLITE (DB Browser for SQLITE) and its all about that.
I've had the same problem for both my windows application (C#) and web application (ASP.net). I usually use SQLite because I found it more easier, especially when I worked with connection strings. But the main obstacle for me was to put a relative path in my code, so I can publish it without worrying about being unable to find the database. I've tried many things(using "|Data Directory|", "~/", "./", ...), and none of them works until I found these solutions. It seems the code is working for me, but wonder if I'm using them right?!
Web Application:
SQLiteConnection sql_con = new SQLiteConnection("Data Source =" + Server.MapPath("~/") + "mydb.db; Version = 3; New = false;);
Windows App:
SQLiteConnection sql_con = new SQLiteConnection("Data Source =" + System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "mydb.db; Version = 3; New = false; Read Only = true");
just replace your .database file into \bin\Debug in project folder, because in your case compiler creates DB file with same name but its totally empty 0bytes
Does anyone know how to write to an excel file (.xls) via OLEDB in C#? I'm doing the following:
OleDbCommand dbCmd = new OleDbCommand("CREATE TABLE [test$] (...)", connection);
dbCmd.CommandTimeout = mTimeout;
results = dbCmd.ExecuteNonQuery();
But I get an OleDbException thrown with message:
"Cannot modify the design of table
'test$'. It is in a read-only
database."
My connection seems fine and I can select data fine but I can't seem to insert data into the excel file, does anyone know how I get read/write access to the excel file via OLEDB?
I was also looking for and answer but Zorantula's solution didn't work for me.
I found the solution on http://www.cnblogs.com/zwwon/archive/2009/01/09/1372262.html
I removed the ReadOnly=false parameter and the IMEX=1 extended property.
The IMEX=1 property opens the workbook in import mode, so structure-modifying commands (like CREATE TABLE or DROP TABLE) don't work.
My working connection string is:
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=workbook.xls;Mode=ReadWrite;Extended Properties=\"Excel 8.0;HDR=Yes;\";"
You need to add ReadOnly=False; to your connection string
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=fifa_ng_db.xls;Mode=ReadWrite;ReadOnly=false;Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\";
I also had the same problem. Only remove the extended property IMEX=1. That will solve your problem. Your table will be created in your Excel file...
A couple questions:
Does the user that executes your app (you?) have permission to write to the file?
Is the file read-only?
What is your connection string?
If you're using ASP, you'll need to add the IUSER_* user as in this example.
How do I check the permissions for writing to an excel file for my application (I'm using excel 2007)?
The file is not read only, or protected (to my knowledge).
My connection String is:
"Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=fifa_ng_db.xls;Mode=ReadWrite;Extended
Properties=\"Excel
8.0;HDR=Yes;IMEX=1\""
Further to Michael Haren's answer. The account you will need to grant Modify permissions to the XLS file will likely be NETWORK SERVICE if this code is running in an ASP.NET application (it's specified in the IIS Application Pool). To find out exactly what account your code is running as, you can do a simple:
Response.Write(Environment.UserDomainName + "\\" + Environment.UserName);
I was running under ASP.NET, and encountered both "Cannot modify the design..." and "Cannot locate ISAM..." error messages.
I found that I needed to:
a) Use the following connection string:
Provider=Microsoft.Jet.OLEDB.4.0;Mode=ReadWrite;Extended Properties='Excel 8.0;HDR=Yes;';Data Source=" + {path to file};
Note I too had issues with IMEX=1 and with the ReadOnly=false attributes in the connection string.
b) Grant EVERYONE full permissions to the folder in which the file was being written. Normally, ASP.NET runs under the NETWORK SERVICE account, and that already had permissions. However, the OleDb code is unmanaged, so it must run under some other security context. (I am currently too lazy to figure out which account, so I just used EVERYONE.)