3

I have the following code to verify if an MSAccess 2003 database is opened in Exclusive Mode by another app (database already has a password):

OleDbConnectionStringBuilder conString = new OleDbConnectionStringBuilder();
conString.Provider = "Microsoft.Jet.OLEDB.4.0";
conString.DataSource = "some path to some mdb file";
// I don't care about the password, 
// I just whant to know if it is opened in Exclusive Mode
conString["Jet OLEDB:Database Password"] = String.Empty;
conString["Mode"] = "Share Deny None";
string completeConnStr = conString.ConnectionString;

using (OleDbConnection con = new OleDbConnection(completeConnStr))
{
      try
      {
         con.Open();
         con.Close();
      }
      catch (Exception ex)
      {
         string s = ex.Message;
      }
}

When the database is opened in Exclusive Mode it doesn't care about the password, it throws an OleDbException with the following message: "File is already in use". When the database is not in exclusive mode and receives the wrong password it throws an OleDbException with a message: "It is not a valid password".

How can I identify these two exceptions? password verification is made in another method, so I just want to know if the database is opened in exclusive mode before annoying the user with the "Enter Password please" dialog.

Broken_Window
  • 2,037
  • 3
  • 21
  • 47
  • 1
    Don't use the `Message` property of an exception to tell you what the exception means. That's just human-readable text, and Microsoft gets to change the text, or use the same exception with different text. Ask yourself, for instance, what happens to your code if Microsoft fixes a typo in the message? – John Saunders Apr 11 '13 at 19:41
  • Hi John! That's exactly what I don't want to do: using the message property. There must be another way to identify these exceptions. – Broken_Window Apr 11 '13 at 19:49

1 Answers1

6

The OleDbException class provides the Errors property which in fact is a OleDbErrorCollection. This collection contains OleDbError objects which provides information about the error.

You could use the SQLState property of the OleDbError class to distinguish the two cases:

try
{
  con.Open();
  con.Close();
}
catch (OleDbException dbException)
{
  switch (dbException.Errors[0].SQLState)
  {
    case "3031": // Authentication failed...
      MessageBox.Show("Authentication failed...");
      break;
    case "3045": // File already in use...
      MessageBox.Show("Database already in use...");
      break;
    default:
      break;
  }          
}

Please see this link for more information about the possible errors.

Hans
  • 12,902
  • 2
  • 57
  • 60