[C#] Opcje w programie

Witam

Mam bardzo denerwujący problem. Chciałem zrobić sobie opcje w programie, dodałem plik settings, dodałem poszczególne opcje i chciałem zrobić coś na zasadzie wywoływania na początku że gdy np. plik z bazą danych nie jest wybrany to wyświetli się komunikat. Niestety nie wiem gdzie się zapisują dane. Przejrzałem pliki w projekcie, nie ma ani jednej wzmianki o ścieżce którą wybrałem. Wziąłem wybrałem ścieżkę do pliku a następnie zapisałem

Properties.Opcje.Default.DATABASE_PATH = BazaOpenFileDialog.FileName;

Properties.Opcje.Default.Save();

I teraz pytanie, gdzie on zapisał tą ścieżkę? Właśnie mi TotalCommander skanuje cały dysk zaglądając do środka plików szukając wybranej ścieżki. Usunąłem wszystkie pliki z projektu po za samym kodem, usunąłem wszystkie pliki jakie znalazłem w folderze Appdata\Local i Appdata\Roaming i mimo to że nigdzie nie znalazłem pliku który by miał wpisane “c:\baza.accdb” to mimo wszystko program pamięta tą ścieżkę. Usunąłem wszystkie pliki z opcjami i dodałem na nowo i on nadal pamięta. Clean, Rebuild nic nie pomaga, mimo że nigdzie nie jest zapisana ta ścieżka to program nadal ją pamięta.

Robiłem coś podobnego przy grze w kuki (Gomoku). Gdy pliku nie było został wyświetlany komunikat i tworzony plik z domyślnymi wartościami.

Plik taki można umieścić w katalogu bin/Debug czyli tam gdzie się kompiluje projekt. Można wówczas zrobić coś takiego (fragment kodu żywcem wzięty z mojej gry):

try

            {

                plik = new FileStream("settings.conf", FileMode.Open); //próba otwarcia pliku settings.conf zawierającego ustawienia gry

            }

            catch (FileNotFoundException)

            {

                //w razie niepowodzenia zostanie wyświetlony komunikat o błędzie

                MessageBox.Show("Błąd pliku konfiguracyjnego settings.conf. Plik nie istnieje lub nie można utworzyć pliku.\r\nBłąd ten prawdopodobnie zostanie usunięty przy kolejnym uruchomieniu aplikacji.", "Błąd konfiguracyjny", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //próba otwarcia lub utworzenia pliku settings.conf

                plik = new FileStream("settings.conf", FileMode.OpenOrCreate);

                //zmienna do pisania do pliku

                StreamWriter save = new StreamWriter(plik);

                //wpisanie domyślnych ustawień

                save.Write(setting[0] + "\r\n" + setting[1] + "\r\n" + setting[2] + "\r\n" + setting[3] + "\r\n" + setting[4] + "\r\n" + setting[5] + "\r\n" + setting[6]);

                //zakończenie pracy z plikiem i całej aplikacji

                //powinna się ona wczytać bezproblemowo po ponownym jej otworzeniu

                save.Flush();

                save.Close();

                this.Close();

                return;

            }

Ja oczywiście mogę zrobić swój system opcji jednak dla wygody chciałem skorzystać z wbudowanego. I o to tutaj właśnie pytam. Czemu mimo że nigdzie na dysku nie jest zapisany żaden plik ze ścieżką którą wybrałem to program zna tą ścieżkę mimo że w żadnym pliku konfiguracyjnym nie ma nawet o tym wzmianki.

Pomyślałeś o rejestrze?

O rejestrze nie pomyślałem, nie sądziłem żeby program ingerował w rejestr skoro tworzy sobie kilka plików dodatkowych i jednej jest ewidentnie plikiem XML i ma element . No ale już skanuje rejestr w poszukiwaniu tych danych.

A próbowałeś wejść w Properties/Settings.settings w VS i tam wybrać View Code by wyświetlić plik Settings.cs?

Próbowałem i czystka. Jak wyżej napisałem usuwałem nawet pliki settings i dodawałem je na nowo i oczywiście program nadal pamięta ścieżkę w zmiennej. Wystarczy dać np.

MessageBox.Show(Properties.Opcje.Default.DATABASE_PATH);

I wyświetli nam ładnie.

Po dłuższej walce z silnikami wyszukiwania i ich brakiem opcji szukania w plikach ukrytych znalazłem W folderze User\AppData\Local\Microsoft\ wszystko związane z moją aplikacją i ruszyło. Tylko czemu on plik konfiguracyjny zapisuje gdzieś nie wiadomo gdzie zamiast zapisać w tych plikach które tworzy?

Teraz druga kwestia.

Może pasowałoby założyć nowy temat do tego ale nie chce mi się.

mam kod taki

switch(MessageBox.Show("Tekst","Tekst",MessageBoxButtons.YesNo))

{

case System.Windows.Forms.DialogResult.Yes:

//jakiś kod

break;

case System.Windows.Forms.DialogResult.No:

// zamknięcie programu

break;

}

Niestety nie działa zamknięcie programu zrobiłem nawet tak Application.Exit(); this.Close();

switch(MessageBox.Show("Tekst","Tekst",MessageBoxButtons.YesNo))

{

case System.Windows.Forms.DialogResult.Yes:

Application.Exit();

this.Close();

break;

case System.Windows.Forms.DialogResult.No:

Application.Exit();

this.Close();

break;

}

Nadal nie zamyka programu, ma ktoś jakiś pomysł?

@Marcin511

Ten artykuł http://www.codeproject.com/KB/vb/appsettings2005.aspx opisuje przede wszystkim pełne ścieżki używane w Windows XP, ale i tak najistotniejszy jest następujący fragment tych ścieżek, który jest niezależny od używanego systemu operacyjnego: __\user.config. Jeśli plik z ustawieniami konfiguracyjnymi aplikacji zapisał Ci się w folderze %USERPROFILE%\AppData\Local\Microsoft\ to jedynym tego wyjaśnieniem jest to, że w pliku AssemblyInfo w atrybucie AssemblyCompany wpisałeś Microsoft. Rozumiem, że pracujesz w Microsoft? :wink: Poza tym nie ma potrzeby używać Application.Exit();. Wystarczy, że zamkniesz okno głównej form-y, zrobisz co masz zrobić w zdarzeniach FormClosing i FormClosed i już.

Niestety to nie działa tak do końca jakbym chciał bo kod wygląda tak

public FormaGlowna()

{

InitializeComponent();

CheckOptions();

}

i problem leży tutaj. Jeśli pozwolę wykonać się konstruktorowi FormaGlowna() to this.Close() działa (np. podpięte pod jakimś przyciskiem). Natomiast jeśli spróbuje zamknąć formę zanim wykona się wszystko co w tym konstruktorze jest to kod funkcji CheckOptions() wykonuje się do samego końca. Następnie po zakończeniu funkcji CheckOptions dostaję komunikat w linijce

Application.Run(new FormaGlowna());

o treści

A co do opcji to rozumiem, że jeśli chce mieć opcje w katalogu z aplikacją to muszę sobie napisać jakiś system opcji?

  1. CheckOptions(); przenieś do zdarzenia Load form-y. Konstruktora form-y nie ruszaj.

  2. “System opcji” (jak to określasz) możesz spokojnie zrobić przy użyciu Settings. W Visual Studio jest świetny generator, który znacznie upraszcza wiązanie poszczególnych właściwości kontrolek z ustawieniami zapisanymi w pliku konfiguracyjnym http://i54.tinypic.com/2h87j43.png. Jak to zastosujesz to właściwości poszczególnych kontrolek będą automatycznie po włączeniu programu ustawiane na takie wartości jakie znajdują się w pliku konfiguracyjnym aplikacji. Jedynie będziesz musiał pamiętać o tym, aby w zdarzeniu FormClosing przepisywać wartości kontrolek do Settings-ów i następnie wywoływać Save() (chyba, że zrobisz aplikację VB .NET, bo tam jest to robione automatycznie).

Już też próbowałem z Load. Chodzi o to że jeśli ktoś nie wybierze bazy danych program ma się zakończyć. Niestety this.Close() umieszczone w zdarzeniu Load nie działa.

Musi działać, bo sam nie raz tak robiłem. Problem leży gdzieś indziej. I co to znaczy, że nie działa? Jakiś komunikat błędu jest?

Forma się ładuje bez problemu. Po prostu się pojawia. Utworzyłem nowy projekt i w zdarzeniu Load umieściłem this.Close() i działa. U mnie w projekcie nie działa.

Oooooo już. W zdarzeniu formClosing miałem wywołanie funkcji zapisującej dane. Ale skoro żadne dane nie zostały załadowane to nie było co zapisać a że co się da jest w sekcjach try catch to wyjątków mi nie wyświetliło bo wyłączyłem je ostatnio bo tamto było już w moim uznaniu dopracowane. I automatycznie wyjątek w FormClosing = przerwanie procesu zamykania :wink: