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
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.
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.
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.
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;
}
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? 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?
CheckOptions(); przenieś do zdarzenia Load form-y. Konstruktora form-y nie ruszaj.
“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.
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