11

Recently I have run into the issue of the C# program I am creating throwing an exception Could not find file C:\windows\system32\qbcdb.mdb. It's odd because I have never ran into this issue before when deploying my program via Advanced Installer. I didn't change anything but for some reason this error keeps happening (screenshot of the exception box - https://i.stack.imgur.com/QaLUC.jpg).

I've no idea on what to include in this question to help explain my problem more, so here is my App.config file (read on a site it may be tied to that, but again, I've never had any issues so far):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    <connectionStrings>
        <add name="QBC.Properties.Settings.qbcdbConnectionString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\qbcdb.mdb"
            providerName="System.Data.OleDb" />
    </connectionStrings>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

Insert into db method:

#region inserts the data into the database
private void InsertData()
{
   using (dbConn)
   {
      dbConn.Open();

            using (dbCmd = new OleDbCommand("INSERT INTO members (household_head, birthday, phone, email, address, status, spouse, spouse_birthday, spouse_phone, spouse_email, " +
              "anniversary, spouse_status, child1, child1_birthday, child1_email, " +
         "child2, child2_birthday, child2_email, child3, child3_birthday, child3_email, child4, child4_birthday, child4_email, child5, child5_birthday, child5_email," +
         "child6, child6_birthday, child6_email, child7, child7_birthday, child7_email) " +
         "VALUES (@txtBox_householdHead, @txtBox_householdHeadBirthday, @txtBox_householdHeadPhone, @txtBox_householdHeadEmail, @txtBox_householdHeadAddress, @txtBox_householdHeadStatus, " +
         "@txtBox_spouse, @txtBox_spouseBirthday, @txtBox_spousePhone, @txtBox_spouseEmail, @txtBox_Anniversary, @txtBox_spouseStatus, " +
         "@txtBox_child1, @txtBox_child1Birthday, @txtBox_child1Email, " +
         "@txtBox_child2, @txtBox_child2Birthday, @txtBox_child2Email, @txtBox_child3, @txtBox_child3Birthday, @txtBox_child3Email, @txtBox_child4, @txtBox_child4Birthday, @txtBox_child4Email, " +
         "@txtBox_child5, @txtBox_child5Birthday, @txtBox_child5Email, @txtBox_child6, @txtBox_child6Birthday, @txtBox_child6Email, @txtBox_child7, @txtBox_child7Birthday, @txtBox_child7Email)", dbConn))
            {
                try
                {
                    InsertDBParameters(ref dbCmd);

                    dbCmd.ExecuteNonQuery();
                }
                catch (OleDbException ex)
                {
                    MessageBox.Show(ex.ToString());
                    return;
                }
                finally
                {
                    dbConn.Close();
                }
            }


            MessageBox.Show("Record inserted.");

            ClearAll(this);
        }


}
#endregion


#region creates the db parameters
private void InsertDBParameters(ref OleDbCommand cmd)
{

    foreach (Control c in Controls)
    {
        if (c is TextBox)
        {
            listOfTextboxes.Add(new KeyValuePair<string, string>(((TextBox)c).Name, ((TextBox)c).Text));
            }
        }

        for (int i = 0; i < listOfTextboxes.Count; i++)
        {
            cmd.Parameters.AddWithValue(String.Format("@{0}", listOfTextboxes[i].Key.ToString()), listOfTextboxes[i].Value);
        }



 }
 #endregion

Select from db method -

#region displays all members in the database
private void MenuViewMembers_Click(object sender, EventArgs e)
{
        // hide any controls left that may be left over from another option
        HideAllControls(this);



        qbcDataGridView.Font = new Font(qbcDataGridView.Font.FontFamily, 10);

        qbcDataGridView.Location = new Point(30, 100);

        qbcDataGridView.Size = new Size(1500, 500);


        dbConn.Open();

        DataTable dt = new DataTable();


        DbAdapter = new OleDbDataAdapter("select ID, household_head AS head, birthday, phone, email, address, status, spouse, spouse_birthday AS sbirthday, spouse_email AS semail, anniversary," +
            " spouse_status AS sstatus," +
            "child1, child1_birthday AS birthday1, child1_email AS email1, child2, child2_birthday AS birthday2, child3, child3_birthday AS birthday3, child3_email AS email3, " +
            "child4, child4_birthday AS birthday4, child4_email AS email4, child5, child5_birthday AS birthday5, child5_email AS email5," +
            "child6, child6_birthday AS birthday6, child6_email AS email6, child7, child7_birthday AS birthday7, child7_email AS email7 from members", dbConn);
        DbAdapter.Fill(dt);

        for (int i = dt.Columns.Count - 1; i >= 0; i--)
        {
            if (dt.AsEnumerable().All(row => row[i].ToString() == ""))
            {
                dt.Columns.RemoveAt(i);
            }
        }

        qbcDataGridView.DataSource = dt;


        qbcDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

        qbcDataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

        qbcDataGridView.DefaultCellStyle.WrapMode = DataGridViewTriState.True;


        dbConn.Close();

        Controls.Add(qbcDataGridView);
}
#endregion

Inside visual studio, it runs fine, but when I build a msi for it with advanced installer, I receive that error message when I try to insert/select from the database.

I'm sorry if this is not enough information, I don't know what really to provide to help explain my situation.

Thanks!

user2101411
  • 1,204
  • 2
  • 14
  • 33
  • what is DataDirectory in your case? Which path it is? – tym32167 Aug 28 '17 at 12:50
  • the full path it says under qbcdb.mdb properties is `C:\Users\jimmy\OneDrive\documents\visual studio 2017\Projects\QBC\QBC\qbcdb.mdb` – user2101411 Aug 28 '17 at 12:51
  • You have used `DataDirectory` in your ConnectionString means the databse that is updated is located in the subfolder BIN\DEBUG folder of your project. Point the one that is located in the project itself instead of Bin/Debug. https://stackoverflow.com/a/31605045/2946329 – Salah Akbari Aug 28 '17 at 12:52
  • 2
    are you sre? Because I see in question C:\windows\system32\qbcdb.mdb. Seems like data folder or smthg like that was changed for you app – tym32167 Aug 28 '17 at 12:53
  • well when i click on the qbcb,mdb file inside visual studio that is what it is saying (http://imgur.com/G7fwP8X) – user2101411 Aug 28 '17 at 12:54
  • @S.Akbari I never had this issue before and everything was the same. – user2101411 Aug 28 '17 at 12:56
  • this is my connection string: `OleDbConnection dbConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=qbcdb.mdb");` – user2101411 Aug 28 '17 at 12:56
  • It does not matter what is written in visual studio property page. Matter only what is in runtime. Try to setup absolute path instead of DataDirectory in your connection string – tym32167 Aug 28 '17 at 13:01
  • sorry if this is a stupid question but how would I go about doing that? I'm kind of hesitant about it because I've run and built the msi installer before for this while it was the same as it is right now and never had any problems before. – user2101411 Aug 28 '17 at 13:06
  • I read the other posts by @S.Akbari and I have a database outside of BIN/DEBUG, here is a screenshot: http://imgur.com/HNIDHNt – user2101411 Aug 28 '17 at 15:28
  • Maybe this could help: https://stackoverflow.com/questions/12187068/where-is-datadirectory-defined – Michael Csikos Sep 01 '17 at 07:08
  • When you get this error, how did you start the app? By double-clicking the exe file? Or clicking on exe's shortcut? Scheduled task? – Thariq Nugrohotomo Sep 01 '17 at 23:25
  • I fixed it, just added data directory to the connection string and it worked. – user2101411 Sep 02 '17 at 03:30

2 Answers2

0

First of all, C:\windows\system32\ is not the right place to store your runtime data. This approach was not valid since Windows 95 went out of Fashion and even there it only worked because FAT had no way to prevent this. In particular that folder is protected both via rights and processes like Virtualsiation. And this will propably only get worse in the future. So best to not even start with it.

The "proper" place to store this kind of data is in one of the Special Folders. Either the User Specific one or a Windows Wide one. ApplicationData and CommonApplicationData should be the best place for this.

Note that the cross user places will get you into issues if more then one user runs the programm (runas, switch user) and handles are not quickly released. Generally the target should be asumed to not be writeable/only writeable in short bursts if it is a cross user folder.

Christopher
  • 9,634
  • 2
  • 17
  • 31
0

When I build a msi for it with advanced installer, I receive that error message when I try to insert/select from the database.

To troubleshoot this you will need a tool called Process Monitor. Process Monitor traces HDD, Registry, Events & Processes in real-time.

Quickly Start the trace, reproduce the error and quickly Stop the trace when it fails. Then investigate ProcMon's (Filemon) log to see where the application is looking for the AccessDB it can't find. It will be a ACCESS DENIED or a Path Not Found.

From here you can determine where the file should be located. I suspect it will be something like a users permissions to the C:\Windows\system32 is denied. Or the user has a D:\ drive Operating System instead of C:\ or something like that which you can fix probably by specifying the data directory properly.

As a rule of thumb don't use System32 as a dumping ground for your files. The Access Database should be in Program Files, or the users Data directory, or on a FileShare (if used by > 1 person).

halfer
  • 19,824
  • 17
  • 99
  • 186
Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321