Программа Windows Form не может найти файл mdb (C:\windows\system32\qbcdb.mdb)

Недавно я столкнулся с проблемой программы С#, которую я создаю, бросая исключение Could not find file C:\windows\system32\qbcdb.mdb. Это странно, потому что я никогда не сталкивался с этой проблемой до развертывания моей программы через Advanced Installer. Я ничего не менял, но по какой-то причине эта ошибка продолжает (снимок экрана окна исключения - http://imgur.com/1GLhwmg),

Я не знаю, что включить в этот вопрос, чтобы помочь объяснить мою проблему больше, так что вот мой файл App.config(читайте на сайте, это может быть связано с этим, но опять же, у меня никогда не было любые проблемы до сих пор):

<?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>

Вставить в метод db:

#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

Выберите метод db -

#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

Внутри визуальной студии она работает нормально, но когда я создаю msi для нее с расширенным установщиком, я получаю это сообщение об ошибке при попытке вставить/выбрать из базы данных.

Прошу прощения, если этого недостаточно, я не знаю, что действительно нужно, чтобы помочь объяснить мою ситуацию.

Спасибо!

Ответ 1

Прежде всего, C:\windows\system32\ не в нужном месте для хранения ваших данных во время выполнения. Этот подход недействителен, так как Windows 95 вышел из моды и даже там он работал только потому, что FAT не смог предотвратить это. В частности, эта папка защищена как правами, так и процессами, такими как Virtualsiation. И это будет только ухудшаться в будущем. Поэтому лучше не начинать с него.

"Правильное" место для хранения данных такого типа находится в одном из Special Folders. Либо пользовательский, либо один Windows. ApplicationData и CommonApplicationData должны быть лучшим местом для этого.

Обратите внимание, что места для кросс-пользователей будут вызывать проблемы, если более один пользователь запускает программу (runas, switch user), и ручки не будут быстро выпущены. Как правило, цель должна быть принята, чтобы ее нельзя было записывать/записывать только в коротких очередях, если она представляет собой папку с несколькими пользователями.

Ответ 2

Когда я создаю msi для него с расширенным установщиком, я получаю это сообщение об ошибке при попытке вставить/выбрать из базы данных.

Чтобы устранить эту проблему, вам понадобится инструмент Process Monitor. Proces sMonitor отслеживает HDD, реестр, события и процессы в режиме реального времени.

Быстро запустить трассировку, воспроизвести ошибку и быстро остановить трассировку при ее сбое. Затем исследуйте журнал ProcMon (Filemon), чтобы узнать, где приложение ищет AccessDB, который он не может найти. Это будет ACCESS DENIED или Path Not Found.

Здесь вы можете определить, где должен находиться файл. Я подозреваю, что это будет что-то вроде прав доступа пользователей к C:\Windows\system32. Если у пользователя есть операционная система D:\вместо операционной системы C:\или что-то вроде этого, которое вы можете исправить, указав данные каталог правильно.

Как правило, не используйте System32 как свалку для ваших файлов. База данных доступа должна находиться в программных файлах или в каталоге данных пользователей или в файле FileShare (если используется > 1 человек).