I have a Windows Service that hangs when opening an OLEDB-connection to an Excel-file, like this:
using (var connection = new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ fileName + ";Extended Properties=\"Excel 8.0\""))
{
connection.Open();
// start using the connection
}
This code works fine when running as a console application. When I debug the Windows Service with Visual Studio, I can step into the code until I hit the call to connection.Open(). At that point, the thread hangs. No exception is thrown. Visual Studio remains responsive, until I hit the "Break All" or "Stop Debugging" button. At that point, Visual Studio also hangs. When I kill the process, Visual Studio becomes responsive again.
Does anyone know why this happens and how to solve it?
EDIT: fileName is an absolute path; the file was written by the service itself.
After unsuccessfully trying to do this inside the Windows Service, I extracted the business logic into a separate Console Application, and just call that application from within Windows Service. Seems to work fine.
I do not know why this happens, but have you tried to narrow it down by trying to open the file and simply load it into a byte array - to determine whether the issue is with the file system / permissions / etc... rather than OLE DB? If you can open and load the file into a byte array, but OLE DB still hangs, is the CPU pegged which would indicate that there might be something about the file which OLE DB cannot handle?
If you cannot get this to work with OLE DB, have you considered a 3rd party xls / xlsx library like SpreadsheetGear for .NET? You can see live samples here and download a free trial here.
Disclaimer: I own SpreadsheetGear LLC
Related
In my ASP .Net application, I am using 'PDFTron 6.6.0.38591'.
We are using following code to convert Office documents to XOD:
string fileName = Path.GetFileName(pdfTronServiceRequest.FilePath);
fileName = ConstructConvertionFileName(fileName);
outFileName = Path.Combine(outputPath, fileName);
pdftron.PDF.Convert.ToXod(pdfTronServiceRequest.FilePath, outFileName);
response.Result = outFileName;
This code works well for filetypes like docx, xlsx, however for Powerpoint files, no response is returned(request timed out).
On checking the Task Manager window, we can see that a process for 'POWERPNT.exe' is started. However, this process never ends up itself(unlike that in case of word, excel upload).
Also, if I manually ends up this process, the conversion to XOD is successful and response is coming out correctly.
Also, please note that we are facing this issue only when we deploy the code on our test environments. Locally, PPT upload is working fine.
Let me know if you need any other information.
First, you should be running a licensed version of PowerPoint, not a trial/eval one. In particular, the account (including a Service/App Pool account) needs to have accepted the MS office licensing to make sure Office is a fully licensed product.
Also, is this happening with any ppt file or only certain ones? If certain ones, then try using one of the following two flags.
pdftron.PDF.Convert.Printer.SetMode(mode)
e_printer_only
e_interop_only
Finally, switch to the latest version. Which at the very least should provide a lot more debugging info in the exception message.
I am creating a plugin for AutoCAD which uses an external Database(SQLite).
and on rare occasions i am getting the "table not found" error. Its driving me crazy. I have seen plenty of forums for answers could not find a solution.
it is working on most cases only few instances it throwing this error.
How do I solve this issue.
I am using relative path to the DB and it lies within the Debug/ release folder.
What is the best approach to attach a db to a application (in my case its a .dll not exe)
thanks guys for reply...Sorry I didnt get any email notification...
Here is the information you requested.
I have a seperate class-which handles connections.
here is how i I connect to the DB.
public static SQLiteConnection GetConnection()
{
string conn_string = string.Format("Data Source=./sdf_db1.s3db");
SQLiteConnection conn = new SQLiteConnection(conn_string);
if (!System.IO.File.Exists("./sdf_db1.s3db"))
{
Global.variables.mess_out_exception("Missing Database file", "Error");
}
return conn;
}
Since this is a plugin for AutoCAD Civil3D it resides in the Appdata\autodesk folder to load on start-up. Everything about the app is working great except rarely I get the table not found error..looks like may be the relative path cannot resolve quickly when the application is started.
I have difficulty finding the absolute path if I tried to use "Application.ExecutablePath;" and few other things which I find online..all I get is the location of Acad.exe not the location of the plugin.
How do I get the absolute path of the location of the plugin to get the location of the DB(since the DB and .dll lies in the same folder).
How do I use both absolute and relative path in the connection string (so if the relative path fails the code can try to locate the db using the absolute path).
Any other suggestion would be great. Thanks
I Found the cause for the issue,
When I run the application and close the application correctly (Means after completing all the process) it works fine I dont get any error message...
I get the error only when I close the window of the application in between. Looks like the connection opened for the DB is still busy if I try to run the application.
Get the path of the plugin with
var asmpath = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location );
Why not take an alternate route?
Instead of trying to find your DLL and associated SQLite database, I would recommend that you install them in a specific location. This way you can easily package it with an installer.
You can utilize automatic loading of .NET modules through AutoCAD with registry keys:
http://through-the-interface.typepad.com/through_the_interface/2006/09/automatic_loadi.html
With this, you can simply install your AutoCAD plugins as if they were a normal program, and get AutoCAD to load them for you on launch.
I am currently in the process of making an application that runs 24/7 and constantly collects information from an OPC-sever.
What I need to do now is to send this information to a database (.accdb-file). This need to happen very, very quickly. I fetch a new value from the server every millisecond and I need to send that value to the database at the same speed. Lastly I'm compressing the database to a .zip-file at 00:00 every day.
I have been searching the web like a maniac but I can't seem to find an "Up-to-date" tutorial. Every one I have found so far uses "Microsoft.Jet.OLEDB.4.0" as provider but it doesn't exsist on my Windows 7 PC.
I have made a small application to test connections with and I'll attach my current code bellow to give you a hint of what I have tried so far, none of this seems to work, though.
private void button1_Click(object sender, EventArgs e)
{
System.Reflection.Assembly oAssembly = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream oStream = oAssembly.GetManifestResourceStream("RSLogixDB.accdb");
System.IO.FileStream fileStream = new System.IO.FileStream("C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb", System.IO.FileMode.Create);
byte[] abyt = new byte[oStream.Length];
oStream.Read(abyt, 0, (int)oStream.Length);
fileStream.Write(abyt, 0, (int)oStream.Length);
fileStream.Close();
if (fileStream != null)
{
fileStream.Close();
fileStream = null;
}
if (oStream != null)
{
oStream = null;
}
}
This is the first approach I tried, here I use a homemade class that is used for creating and writing to files. It didn't work for .accdb-files, unfotunately. (The comments on the first lines include providers that I have tried.
private void button1_Click(object sender, EventArgs e)
{
//sFileDia.ShowDialog();
//Provider=Microsoft.ACE.OLEDB.12.0
//Povider=.NET Framework Data Provider for OLE DB
//Povider=Microsoft.Jet.OLEDB.4.0
//Driver={Microsoft Access Driver (*.mdb, *.accdb)};
//Data Source=C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb;
//Persist Security Info=False;
//Provider=Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb;Persist Security Info=False
string RSLogixDB = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb;Persist Security Info=False";
string RSLogixDBPath = "C:\\Users\\sezettersth\\Documents\\RSLogixDB.accdb";
OleDbConnection connection = new OleDbConnection(RSLogixDB);
string connectionStr = connection.ConnectionString;
//OleDbDataReader dataReader = new OleDbDataReader(RSLogixDB);
ImportExport textwriter = new ImportExport();
textwriter.setExportPath(RSLogixDBPath);
textwriter.endExport();
}
There has to be a simple solution to this, I can't be the only one using Access without the "Microsoft.Jet.OLEDB.4.0" provider.
(I haven't started the code for zipping the file and if you have an idea on how to do that I'm happy to hear it, but the main focus here is the database issue.)
UPDATE: The problem might not lie on the provider as I initially though, Microsoft.ACE.OLEDB.12.0 allows me to create a .accdb-file but it is just an empty txt-file with a fancy extension basically and it cannot be opened or used with MS Access. How do I make a working .accdb-file?
Regarding your code
To be honest, I'm at a loss at what you are trying to achieve in the code samples you presented.
From what I can see, you are simply creating a file RSLogixDB.accdb.
Maybe I'm missing something, but that's not how you create a database at all.
Have you looked and tried the code in the answers to these SO questions:
How i Create Access Database at runtime in C#?
How to create Microsoft Access database in C# programmatically?
Now, some more explanations.
Jet vs ACE
First, the ACCDB file format is the result of a complete revamp of Jet now called ACE.
It's only used with Access 2007/2010 and contains new functionalities that are not backward compatible.
To open such a file, you must have either Access 2007/2010 installed (or the free Access Runtime at least) or the specific ACE drivers from Microsoft.
Regarding 32/64 bitness
For the sake of your sanity, regardless of your OS bitness, only use Office and Access 32 bits. Even Microsoft doesn't recommend using the 64 bits version except if you are pushing Excel to its limits.
you can't mix Office 32 bits and 64 bits applications
you can't install the 32 bits and 64 bits ACE drivers on the same machine
Use either the version 2007 or 2010 of the ACE drivers, but avoid having both installed.
make sure that your .Net application is compiled for the same bitness as Access/ACE driver installed (so you should specifically compile to x86 if you follow the advice above, not AnyCPU!).
Performance
You can get very decent performance with an Access database if you keep a few rules:
if possible, keep the database on the same machine as the application that will write to it (avoid network slowdowns)
if your application is the only one using the database, open the database in exclusive mode instead of shared mode:
// Share Mode=16 - use if multiple users must have simultaneous access to the db
string constr = #"Provider=Microsoft.ACE.OLEDB.12.0;Mode=16;Data Source=C:\...\RSLogixDB.accdb;user id=;password=;";
// Share Mode=12 - exclusive mode if only your app needs access to the db
string constr = #"Provider=Microsoft.ACE.OLEDB.12.0;Mode=12;Data Source=C:\...\RSLogixDB.accdb;user id=;password=;";
open a dummy connection to the database when your application starts and keep it open until you don't need the database (to zip it for instance or when your app shuts down).
This is actually a very important performance improvement: opening a new connection to an Access database is expensive because the driver need to create/destroy/update the .accdl lock file.
If you keep an always-open connection to the database, you will greatly speed-up your read/writes to it. For more info on this subject, please check this article:
Where is the OLE DB connection pooling?
Back to the task
The way I would do what you are trying to achieve:
Use Access to manually create a simple database RSLogixDB.accdb with the table that would hold the data.
Also create a dummy table in it with little or no data. We'll use it to keep the connection open and avoid the lock file performance issues.
If you need to re-create the database every day from scratch, then keep a copy of that original database as a template, then copy that template and fill the copy with the new daily data.
If you're the only user of the db, open it in exclusive mode.
Open a connection and read data from the dummy table, but don't close it. Keep it open.
save data to your data table all day long
at midnight, close the database (close the dummy table), make sure the lock file .accdl has disapeared then zip the database.
Replace the database by the template if you need to start with an empty db.
I would also compact the database to reduce its size before zipping it.
If the standard performance of ADO.Net data access is insufficient for your case, have a look at using the native DAO routines. Check out the answer to this SO question:
Writing large number of records (bulk insert) to Access in .NET/C#
If you ever need the connection string for connecting to a particular database then the first stop should always be http://www.connectionstrings.com/
For Access you'd probably find this page helpful: http://www.connectionstrings.com/access-2007
I found this for you. Connecting to MS Access (Windows 7)
also this forum thread will help you.
Thanks
Paul.
I believe that your connection cannot be established because the Jet OLEDB driver does not come with Windows 7, but needs to be installed separately. One way to do this is to install Microsoft Access, another way is to look for the MDAC redistributable package from Microsoft (MDAC = Microsoft Data Access Components).
You can check if - and if yes - which version of MDAC you have by following the instructions on the following link:
http://support.microsoft.com/kb/301202/en-us
As for now (AUG22), you can have both x32- and x64-bit OLEDB/ACE (/MS Access Database Microsoft.Jet.OLEDB.4.0 and Microsoft.ACE.OLEDB.12.0) drivers installed on the same PC:
I have followed the setup instructions from this article "Using Database Libraries with 32-bit and 64-bit Altium Design Software on the same Computer" and they worked well for me for Win10 Professional x64 v.21H2 (Build 19044.1826) with MS Office x32.
I'm using x32 OLEDB drivers with the legacy VS2019 .NET Framework 4.7.x applications' solutions and x64 ACE drivers with the (modern) VS2022 applications' solutions.
When I try to build a project twice in successon, i get the following error
Error 2 Unable to copy file "obj\x86\Release\iFileUploader.exe"
to "bin\Release\iFileUploader.exe". The process cannot access the
file 'bin\Release\iFileUploader.exe' because it is being used by another process.
If I close Visual Studio and reopen it, I can compile it again but only once.
I have my projects hosted on a Windows network share. The server runs Windows 2008 R2 and Im on a Windows 7 machine and Ive tried setting everyone full control on the share and the folder permission, to no avail.
Ive even run the Unlocker program and checked the Windows Share & Storage Manager to see if anything is using it and nothing is! I cant delete the file when this happens either until I close VS.
Is there a setting I am missing in Visual Studio?!
UPDATE
Have removed all antivirus/antispam, disabled firewall.. so zero security.
Have disabled "Enable the Visual Studio hosting process"
Visual Studio is some how the colprupt with not releasing the handle
UPDATE
Another thread that has exactly the same problem but from years ago !!
Destroy process-less console windows left by Visual Studio debug sessions
UPDATE
I copied the files locally, and that didnt work. So I created a new project and then copied all the code in to the new project and now its working (with the files stored locally)
check your antivirus program is using it or not.
Alternatively use Process Explorer and find for the string - "iFileUploader.exe" and see who's using it. You can easily get the handle and close it.
Several points:
Check if you don't have a process iFileUploader.exe already running in the Windows Task Manager.
Check that nobody is not running a project that could use iFileUploader.exe.
Christian even if you are have your Stream in a using(){} do not declare a new variable of StreamReader for example do not do this
using(StreamReader streamReade = new StreamReader)
{
..... // if you do you will run into that stream being locked
}
//Declare the StreamReader variable out side of the using and then within the using do something like this.
StreamReader streamReader = null
using(streamReader = new StreamReader()
{
}
Make sure that where you have created an instance of the StreamReader or StreamWriter that you have closed the stream.
For example I would create at the application level a StreamReader / StreamWriter instance and set it to null
Class SomeClass
{
public StreamWriter streamwrtFileToCreate = null;
public FileStream fstreamFileStream = null
public SomeMethod(string FileName, string FilePath)
{
FileStream fstreamFileStream = new FileStream(#FileName + #FilePath, FileMode.Create);
streamwrtFileToCreate = new StreamWriter(fstreamUpdateRpt);
streamwrtUpdateRpt.AutoFlush = true;
}
}
Also it would help if you post the exact example of code that you are using when you create the FileStream Instance
I had this issue in VS 2012 windows 7.
Root cause is Avast Antivirus.
Fix is disable Avast whenever needed to work on C++ console
applications
(or)
->Go to Avast Settings
->Active Protection
->File System Shield (Customize)
->uncheck Scan programs when executing
I used the PostBuildevnt script to launch the application form link
http://blogs.msdn.com/b/astebner/archive/2006/08/12/696833.aspx?wa=wsignin1.0&CommentPosted=true
and launching the app successfully.I am using the sqllite for app.
I added the DB file in Application Folder/DataBase and using the following code to open the Db file.
string ConnectionString = "data source=" + Path.GetFullPath(".") + "\\DataBase\\CATTDB.db";
If i launch the app from the installation wizard,it is not connecting to db file.it is throwing the error like "Unable to open the file".
If i launch from the start menu or desktop icon ,it is working fine..
What is the problem here?
please help me..
It could be that your working directoy is different when started from the installer...
What does Path.GetFullPath(".") return in this case (log and/or display the value)?
There is always the issue of permission/rights - depending on your OS (i.e. Windows 7...) and the user your running the app with (i.a. Administrator?) for security reasons you are not allowed to write in the application directory... if you need someplace with read+write you should use http://msdn.microsoft.com/de-de/library/system.windows.forms.application.userappdatapath.aspx
Just check whether the db is in that path -if not copy it there- and use it there...
Other locations could be ApplicationData/CommonApplicationData/LocalApplicationData from http://msdn.microsoft.com/de-de/library/14tx8hby.aspx and http://msdn.microsoft.com/de-de/library/system.environment.specialfolder.aspx
All the files are copying correctly..
I tried with Application.ExecutablePath instead of Path.GetFullPath(".")
it work's great...