enter image description hereI am using a C# dll using pythonnet on python 2.7.13 (which uses other dll files and .mdb database files) to make some technical calculations. This dll files does not have a good documentation (only namespaces, class and method names). Well the program in most PC Works Fine but in all office computers it throws a runtime Error from Dll files (my doubt is connection with database). This dll files are compiled to target .NET 4.0 (in office computers is installed .NET 4.7.1 or other versions newer than 4.0) and EntityFramework is also being used (programs target 5.0 and this is a dll file in program folder, but in office computers is installed EntityFramework 6.2 tool). Microsoft database Engine 2010 is also installed in those computers.
In every other computer that I have tested the program it works perfectly. In office computers I found a group of input data for which program works, but anyway this is not correct because it should work also for the default data.
To make tests in office computers I have compiled python code using PyInstaller (I repeat, compiled version work fine in other PCs).
I am using .NET Reflector to decompile dll files and programs Exception to find the Error. The method that throws Exception is in the following code.
Thanks in advance!
public int LoadRanghiAmmessi(int[] vRanghi, string geometria)
{
int index = 0;
CrConnection connection = new CrConnection(this.PathDB);
string query = "SELECT * FROM RanghiAmmessi WHERE (Geometria='" + geometria + "') ORDER BY NRanghi";
OleDbDataReader recordset = connection.GetRecordset(query, #"\Coils.mdb;");
if (!recordset.HasRows)
{
if (recordset != null)
{
recordset.Close();
}
query = "SELECT * FROM RanghiAmmessi WHERE (Geometria='*') ORDER BY NRanghi";
recordset = connection.GetRecordset(query, #"\Coils.mdb;");
while (recordset.Read())
{
vRanghi[index] = int.Parse(recordset["NRanghi"].ToString());
index++;
}
if (recordset != null)
{
recordset.Close();
}
}
return index;
}
public OleDbDataReader GetRecordset(string query, string NomeDB)
{
string connectionString = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + this.PathDB + NomeDB + "Jet OLEDB:Database Password=123456";
this.ChiudiConnessioni();
this.conn = new OleDbConnection(connectionString);
OleDbCommand command = new OleDbCommand(query, this.conn);
try
{
this.ApriConnessione();
return command.ExecuteReader();
}
catch (Exception exception)
{
exception.Message.ToString();
this.ChiudiConnessioni();
return null;
}
}
After many tests I found out that the program is working also in other PC after declaring some objects like function parameters and after compiling running the program as compatible with Windows 7. Before the objects were created like variables and those variables were passed as parameters, (in this case, reasonably the first thought is that the problem is "pass by reference" mechanism and that some values are not inserted in the right mode, but this is not the case because:
- the same exactly code did function very well in most PC (compatibility
problem)
- the same exactly mechanism is used to specify the objects attributes and
to make calculations
In this conditions I would say that it is not clear where the problem was. In the first version installing the SQL Server Express made possible for the program to work well even without last modifications.
Umm... given the details that it works fine on "Other PC", I am guessing that the problem is your so-called database. I don't see in any way, however, how anyone could be certain at what the problem is until it is solved.
Related
I'm working on a C# application that has to read an Access database (.mdb), on Linux. I'm using Mono to compile and run the application.
Suppose I have a test database that I create in Access 2013. It has one table: TestTable, with the default ID column and a testField1 column created with the 'Long Text' type. I insert three rows, with these values for the testField1 column: "foo", "bar", "baz". The database is saved as 'Access 2002-2003 Database (*.mdb)'.
The resulting database (named Test.mdb) is transferred to my Linux box. Just as a sanity check, I can run mdb-export on the database:
$ mdb-export Test.mdb TestTable
ID,testField1
1,"foo"
2,"bar"
3,"baz"
So far, so good. Now, suppose we have a C# program that reads the testField1 column of the table:
using System;
using System.Data.Odbc;
class Program {
public static void Main(string[] args){
try {
OdbcConnection conn = new OdbcConnection("ODBC;Driver=MDBTools;DBQ=/path/to/Test.mdb");
conn.Open();
var command = conn.CreateCommand();
command.CommandText = "SELECT testField1 FROM TestTable";
var reader = command.ExecuteReader();
while(reader.Read()){
Console.WriteLine(reader.GetString(0));
}
} catch(Exception e){
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
}
I would expect that running this program would print "foo", "bar", and "baz". However, compiling and running the program does not yield this output:
$ mcs mdb_odbc.cs -r:System.data.dll
$ mono mdb_odbc.exe
潦o
$ # this line added to show the empty lines
My guess is that this is an encoding issue, but I have no idea how to resolve it. Is there a way to fix my program or the environment that it runs in so that the contents of the database are printed correctly? I believe that it is an issue with either ODBC or MDBTools, because in a similar program, a string equality check against fields of a database fails.
I'm using Ubuntu 16.10. mono --version outputs Mono JIT compiler version 5.4.0.167 (tarball Wed Sep 27 18:38:59 EDT 2017) (I built it from source with this patch applied to fix another issue with ODBC). MDBTools, installed through Apt, is version 0.7.1-4build1, and the odbc-mdbtools package is the same version.
I know that the combination of tools and software I'm using is unusual, but unfortunately, I have to use C#, I probably have to use Mono, I have to use an Access database, and I have to use ODBC to access the database. If there's no other way around it, I suppose I could convert the database to another format (SQLite comes to mind).
I have following C# code in a console application.
Whenever I debug the application and run the query1 (which inserts a new value into the database) and then run query2 (which displays all the entries in the database), I can see the new entry I inserted clearly. However, when I close the application and check the table in the database (in Visual Studio), it is gone. I have no idea why it is not saving.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlServerCe;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = "FlowerShop.sdf";
string fileLocation = "|DataDirectory|\\";
DatabaseAccess dbAccess = new DatabaseAccess();
dbAccess.Connect(fileName, fileLocation);
Console.WriteLine("Connected to the following database:\n"+fileLocation + fileName+"\n");
string query = "Insert into Products(Name, UnitPrice, UnitsInStock) values('NewItem', 500, 90)";
string res = dbAccess.ExecuteQuery(query);
Console.WriteLine(res);
string query2 = "Select * from Products";
string res2 = dbAccess.QueryData(query2);
Console.WriteLine(res2);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
class DatabaseAccess
{
private SqlCeConnection _connection;
public void Connect(string fileName, string fileLocation)
{
Connect(#"Data Source=" + fileLocation + fileName);
}
public void Connect(string connectionString)
{
_connection = new SqlCeConnection(connectionString);
}
public string QueryData(string query)
{
_connection.Open();
using (SqlCeDataAdapter da = new SqlCeDataAdapter(query, _connection))
using (DataSet ds = new DataSet("Data Set"))
{
da.Fill(ds);
_connection.Close();
return ds.Tables[0].ToReadableString(); // a extension method I created
}
}
public string ExecuteQuery(string query)
{
_connection.Open();
using (SqlCeCommand c = new SqlCeCommand(query, _connection))
{
int r = c.ExecuteNonQuery();
_connection.Close();
return r.ToString();
}
}
}
EDIT: Forgot to mention that I am using SQL Server Compact Edition 4 and VS2012 Express.
It is a quite common problem. You use the |DataDirectory| substitution string. This means that, while debugging your app in the Visual Studio environment, the database used by your application is located in the subfolder BIN\DEBUG folder (or x86 variant) of your project. And this works well as you don't have any kind of error connecting to the database and making update operations.
But then, you exit the debug session and you look at your database through the Visual Studio Server Explorer (or any other suitable tool). This window has a different connection string (probably pointing to the copy of your database in the project folder). You search your tables and you don't see the changes.
Then the problem get worse. You restart VS to go hunting for the bug in your app, but you have your database file listed between your project files and the property Copy to Output directory is set to Copy Always. At this point Visual Studio obliges and copies the original database file from the project folder to the output folder (BIN\DEBUG) and thus your previous changes are lost.
Now, your application inserts/updates again the target table, you again can't find any error in your code and restart the loop again until you decide to post or search on StackOverflow.
You could stop this problem by clicking on the database file listed in your Solution Explorer and changing the property Copy To Output Directory to Copy If Newer or Never Copy. Also you could update your connectionstring in the Server Explorer to look at the working copy of your database or create a second connection. The first one still points to the database in the project folder while the second one points to the database in the BIN\DEBUG folder. In this way you could keep the original database ready for deployment purposes and schema changes, while, with the second connection you could look at the effective results of your coding efforts.
EDIT Special warning for MS-Access database users. The simple act of looking at your table changes the modified date of your database ALSO if you don't write or change anything. So the flag Copy if Newer kicks in and the database file is copied to the output directory. With Access better use Copy Never.
Committing changes / saving changes across debug sessions is a familiar topic in SQL CE forums. It is something that trips up quite a few people. I'll post links to source articles below, but I wanted to paste the answer that seems to get the best results to the most people:
You have several options to change this behavior. If your sdf file is part of the content of your project, this will affect how data is persisted. Remember that when you debug, all output of your project (including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
Answer Source
Here is a link to some further discussion and how to documentation.
I have following C# code in a console application.
Whenever I debug the application and run the query1 (which inserts a new value into the database) and then run query2 (which displays all the entries in the database), I can see the new entry I inserted clearly. However, when I close the application and check the table in the database (in Visual Studio), it is gone. I have no idea why it is not saving.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlServerCe;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = "FlowerShop.sdf";
string fileLocation = "|DataDirectory|\\";
DatabaseAccess dbAccess = new DatabaseAccess();
dbAccess.Connect(fileName, fileLocation);
Console.WriteLine("Connected to the following database:\n"+fileLocation + fileName+"\n");
string query = "Insert into Products(Name, UnitPrice, UnitsInStock) values('NewItem', 500, 90)";
string res = dbAccess.ExecuteQuery(query);
Console.WriteLine(res);
string query2 = "Select * from Products";
string res2 = dbAccess.QueryData(query2);
Console.WriteLine(res2);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
class DatabaseAccess
{
private SqlCeConnection _connection;
public void Connect(string fileName, string fileLocation)
{
Connect(#"Data Source=" + fileLocation + fileName);
}
public void Connect(string connectionString)
{
_connection = new SqlCeConnection(connectionString);
}
public string QueryData(string query)
{
_connection.Open();
using (SqlCeDataAdapter da = new SqlCeDataAdapter(query, _connection))
using (DataSet ds = new DataSet("Data Set"))
{
da.Fill(ds);
_connection.Close();
return ds.Tables[0].ToReadableString(); // a extension method I created
}
}
public string ExecuteQuery(string query)
{
_connection.Open();
using (SqlCeCommand c = new SqlCeCommand(query, _connection))
{
int r = c.ExecuteNonQuery();
_connection.Close();
return r.ToString();
}
}
}
EDIT: Forgot to mention that I am using SQL Server Compact Edition 4 and VS2012 Express.
It is a quite common problem. You use the |DataDirectory| substitution string. This means that, while debugging your app in the Visual Studio environment, the database used by your application is located in the subfolder BIN\DEBUG folder (or x86 variant) of your project. And this works well as you don't have any kind of error connecting to the database and making update operations.
But then, you exit the debug session and you look at your database through the Visual Studio Server Explorer (or any other suitable tool). This window has a different connection string (probably pointing to the copy of your database in the project folder). You search your tables and you don't see the changes.
Then the problem get worse. You restart VS to go hunting for the bug in your app, but you have your database file listed between your project files and the property Copy to Output directory is set to Copy Always. At this point Visual Studio obliges and copies the original database file from the project folder to the output folder (BIN\DEBUG) and thus your previous changes are lost.
Now, your application inserts/updates again the target table, you again can't find any error in your code and restart the loop again until you decide to post or search on StackOverflow.
You could stop this problem by clicking on the database file listed in your Solution Explorer and changing the property Copy To Output Directory to Copy If Newer or Never Copy. Also you could update your connectionstring in the Server Explorer to look at the working copy of your database or create a second connection. The first one still points to the database in the project folder while the second one points to the database in the BIN\DEBUG folder. In this way you could keep the original database ready for deployment purposes and schema changes, while, with the second connection you could look at the effective results of your coding efforts.
EDIT Special warning for MS-Access database users. The simple act of looking at your table changes the modified date of your database ALSO if you don't write or change anything. So the flag Copy if Newer kicks in and the database file is copied to the output directory. With Access better use Copy Never.
Committing changes / saving changes across debug sessions is a familiar topic in SQL CE forums. It is something that trips up quite a few people. I'll post links to source articles below, but I wanted to paste the answer that seems to get the best results to the most people:
You have several options to change this behavior. If your sdf file is part of the content of your project, this will affect how data is persisted. Remember that when you debug, all output of your project (including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
Answer Source
Here is a link to some further discussion and how to documentation.
I'm developing a small application that will simplify logging, it does so by adding some inputs to an MS Access database through OleDB.
let private conn = new OleDbConnection(connectionString)
let private submitCmd date wins =
let cmd = new OleDbCommand("INSERT INTO ArenaStats ([Date], [Wins]) VALUES (#Date, #Wins)",
Connection = conn, CommandType = CommandType.Text)
["#Date", box date; "#Wins", box wins]
|> List.iter (cmd.Parameters.AddWithValue >> ignore)
cmd
let private submit date wins =
try
conn.Open()
(submitCmd date wins).ExecuteNonQuery() |> ignore
finally
conn.Close()
[<CompiledName "AddEntry">]
let addEntry(date:DateTime, wins:int) =
submit date wins
Now testing this through FSI works just as expected. However, when I consume this API from a C# WPF project it will throw an SEHException at conn.Open(). I am really scratching my head over why this is happening.
Edit
As suggested, I have also tried to implement the same code purely in C# and in the same project, it will throw the same exception at the same place but I am posting the code below for reference.
class MsAccessDatabase : IArenaWinsDatabase {
private OleDbConnection connection = new OleDbConnection(connectionString);
private OleDbCommand SubmitCommand(DateTime date, int wins) {
return new OleDbCommand("INSERT INTO ArenaStats ([Date], [Wins]) VALUES (#Date, #Wins)") {
Connection = connection,
CommandType = System.Data.CommandType.Text,
Parameters = {
new OleDbParameter("#Date", date),
new OleDbParameter("#Wins", wins)
}
};
}
public void Submit(DateTime date, int wins) {
try {
connection.Open();
SubmitCommand(date, wins).ExecuteNonQuery();
}
finally {
connection.Close();
}
}
}
With some help from Philip I was able to figure it out. It seems that by default FSI is configured to run in 64-bit by default while the WPF project is set to "prefer 32-bit". Changing the target platform for the WPF project to 64-bit resolved the issue.
When trying to run the following code:
var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", FilePath);
OleDbConnection OleDbConnection = new System.Data.OleDb.OleDbConnection(connectionString);
OleDbConnection.Open();
An SEHException exception is thrown at runtime, with the error message 'External Component has thrown an Exception'
This will usually occur when the build configuration platform in Visual Studio is incorrect, this can occur in both build configuration platforms, x86 and x64.
This is due to a mismatch between the build configuration platform of your project and the Microsoft Access Database Engine which is installed on your machine.
In order to resolve this error:
Change the build configuration platform in Visual Studio - make sure it matches the Microsoft Access Database Engine version on your machine
Recompile and run your project
The run time error should now be resolved
I know this is a really old thread, but I just ran into the same problem with a different solution.
When I installed the Access Database Engine 2016 Redistributable (x64) for the ACE provider the installer gave me an error that VCRUNTIME140.DLL wasn't installed, but the installer completed anyways and the ACE provider was available.
Uninstalling the Access Database Engine, installing the VC++ 2015 Redistributable R3 (https://www.microsoft.com/en-us/download/confirmation.aspx?id=52685), then re-installing the Access Database Engine solved the problem.
I have following C# code in a console application.
Whenever I debug the application and run the query1 (which inserts a new value into the database) and then run query2 (which displays all the entries in the database), I can see the new entry I inserted clearly. However, when I close the application and check the table in the database (in Visual Studio), it is gone. I have no idea why it is not saving.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlServerCe;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = "FlowerShop.sdf";
string fileLocation = "|DataDirectory|\\";
DatabaseAccess dbAccess = new DatabaseAccess();
dbAccess.Connect(fileName, fileLocation);
Console.WriteLine("Connected to the following database:\n"+fileLocation + fileName+"\n");
string query = "Insert into Products(Name, UnitPrice, UnitsInStock) values('NewItem', 500, 90)";
string res = dbAccess.ExecuteQuery(query);
Console.WriteLine(res);
string query2 = "Select * from Products";
string res2 = dbAccess.QueryData(query2);
Console.WriteLine(res2);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
class DatabaseAccess
{
private SqlCeConnection _connection;
public void Connect(string fileName, string fileLocation)
{
Connect(#"Data Source=" + fileLocation + fileName);
}
public void Connect(string connectionString)
{
_connection = new SqlCeConnection(connectionString);
}
public string QueryData(string query)
{
_connection.Open();
using (SqlCeDataAdapter da = new SqlCeDataAdapter(query, _connection))
using (DataSet ds = new DataSet("Data Set"))
{
da.Fill(ds);
_connection.Close();
return ds.Tables[0].ToReadableString(); // a extension method I created
}
}
public string ExecuteQuery(string query)
{
_connection.Open();
using (SqlCeCommand c = new SqlCeCommand(query, _connection))
{
int r = c.ExecuteNonQuery();
_connection.Close();
return r.ToString();
}
}
}
EDIT: Forgot to mention that I am using SQL Server Compact Edition 4 and VS2012 Express.
It is a quite common problem. You use the |DataDirectory| substitution string. This means that, while debugging your app in the Visual Studio environment, the database used by your application is located in the subfolder BIN\DEBUG folder (or x86 variant) of your project. And this works well as you don't have any kind of error connecting to the database and making update operations.
But then, you exit the debug session and you look at your database through the Visual Studio Server Explorer (or any other suitable tool). This window has a different connection string (probably pointing to the copy of your database in the project folder). You search your tables and you don't see the changes.
Then the problem get worse. You restart VS to go hunting for the bug in your app, but you have your database file listed between your project files and the property Copy to Output directory is set to Copy Always. At this point Visual Studio obliges and copies the original database file from the project folder to the output folder (BIN\DEBUG) and thus your previous changes are lost.
Now, your application inserts/updates again the target table, you again can't find any error in your code and restart the loop again until you decide to post or search on StackOverflow.
You could stop this problem by clicking on the database file listed in your Solution Explorer and changing the property Copy To Output Directory to Copy If Newer or Never Copy. Also you could update your connectionstring in the Server Explorer to look at the working copy of your database or create a second connection. The first one still points to the database in the project folder while the second one points to the database in the BIN\DEBUG folder. In this way you could keep the original database ready for deployment purposes and schema changes, while, with the second connection you could look at the effective results of your coding efforts.
EDIT Special warning for MS-Access database users. The simple act of looking at your table changes the modified date of your database ALSO if you don't write or change anything. So the flag Copy if Newer kicks in and the database file is copied to the output directory. With Access better use Copy Never.
Committing changes / saving changes across debug sessions is a familiar topic in SQL CE forums. It is something that trips up quite a few people. I'll post links to source articles below, but I wanted to paste the answer that seems to get the best results to the most people:
You have several options to change this behavior. If your sdf file is part of the content of your project, this will affect how data is persisted. Remember that when you debug, all output of your project (including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
Answer Source
Here is a link to some further discussion and how to documentation.