Dapatkah saya mengontrol lokasi pengaturan pengguna .NET untuk menghindari kehilangan pengaturan pada peningkatan aplikasi?

104

Saya mencoba menyesuaikan lokasi user.configfile. Saat ini disimpan dengan hash dan nomor versi

%AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\

Saya ingin menjadi agnostik dengan versi aplikasi

%AppData%\[CompanyName]\[ProductName]\

Bisakah ini dilakukan dan bagaimana? Apa implikasinya? Akankah pengguna kehilangan pengaturan mereka dari versi sebelumnya setelah meningkatkan?

Muxa
sumber
Meskipun jawaban uzbones informatif berkaitan dengan lokasi file, saya percaya bahwa Ian lebih tepat dalam hal peningkatan.
Anthony Mastrean
4
@AnthonyMastrean saya pribadi berpikir bahwa pengaturan penting tidak boleh bergantung pada infrastruktur ApplicationSettings yang disediakan Microsoft saya. Muxa seharusnya hanya menyimpan pengaturan di %AppData%\[CompanyName]/[ProductName]tempat yang dapat kita percayai akan tetap ada.
Ian Boyd
2
Tidak diragukan lagi, pengalaman saya yang berkelanjutan dengan aplikasi bawaan dan pengaturan pengguna sangat buruk. Saya merekomendasikan file json di appdata atau programdata.
Anthony Mastrean
Anda juga dapat menyimpan pengaturan Anda di registri. Lihat stackoverflow.com/a/12127888/1273550 untuk implementasi kelas pengaturan alternatif.
Ravi Patel

Jawaban:

39

Untuk menjawab pertanyaan pertama, Anda secara teknis dapat meletakkan file di mana pun Anda inginkan, namun Anda harus mengkodekannya sendiri, karena tempat default file tersebut adalah yang pertama dari dua contoh Anda. ( tautan ke cara melakukannya sendiri )

Adapun pertanyaan kedua, itu tergantung pada bagaimana Anda menyebarkan aplikasi. Jika Anda menerapkan melalui .msi, maka ada dua hash di properti proyek penyiapan (tempat msi dibuat), 'kode pemutakhiran' dan 'kode produk'. Ini menentukan bagaimana msi dapat diinstal, dan jika ia meningkatkan, menimpa, atau menginstal di samping versi lain dari aplikasi yang sama.

Misalnya, jika Anda memiliki dua versi perangkat lunak Anda dan mereka memiliki kode 'peningkatan' yang berbeda, maka untuk windows mereka adalah bagian perangkat lunak yang sama sekali berbeda terlepas dari apa namanya. Namun jika kode 'peningkatan' sama, tetapi kode 'produk' berbeda maka ketika Anda mencoba menginstal msi ke-2 itu akan menanyakan Anda apakah Anda ingin meningkatkan, pada saat mana seharusnya menyalin nilai dari konfigurasi lama ke konfigurasi baru. Jika kedua nilai sama, dan nomor versi tidak berubah maka konfigurasi baru akan berada di lokasi yang sama dengan konfigurasi lama, dan tidak perlu melakukan apa pun. Dokumentasi MSDN

ClickOnce sedikit berbeda, karena lebih berbasis versi ClickOnce # dan jalur URL, namun saya telah menemukan bahwa selama Anda terus 'Publikasikan' ke lokasi yang sama, versi baru aplikasi akan terus menggunakan konfigurasi yang ada. ( tautan ke bagaimana ClickOnce menangani pembaruan )

Saya juga tahu ada cara untuk menggabungkan konfigurasi secara manual selama penginstalan msi menggunakan skrip penginstalan kustom, tetapi saya tidak ingat langkah-langkah yang tepat untuk melakukannya ... (lihat tautan ini untuk mengetahui cara melakukannya dengan web. config)

uzbones
sumber
Bukankah kode pemutakhiran yang seharusnya tetap konstan, dan kode produk yang seharusnya berubah di antara rilis? blogs.msdn.com/b/pusu/archive/2009/06/10/understanding-msi.aspx
estanford
Doh! Anda benar, tidak percaya saya mendapatkannya mundur (dan butuh 2 tahun untuk menangkapnya). Rasanya seperti penandatanganan robo untuk sementara waktu pada satu titik di masa lalu saya :(
uzbones
Apakah itu berarti, hanya pengguna yang memasang yang mendapatkan peningkatan setelannya?
Micha Wiedenmann
79

Saya ingin menambahkan teks kutipan ini sebagai referensi ketika saya memiliki masalah ini di masa mendatang. Seharusnya Anda dapat menginstruksikan infrastruktur ApplicationSettings untuk menyalin pengaturan dari versi sebelumnya dengan memanggil Upgrade :

Properties.Settings.Value.Upgrade();

Dari posting blog FAQ Pengaturan Klien : ( arsip )

T: Mengapa ada nomor versi di jalur user.config? Jika saya menerapkan versi baru aplikasi saya, bukankah pengguna akan kehilangan semua pengaturan yang disimpan oleh versi sebelumnya?

J: Ada beberapa alasan mengapa jalur user.config peka terhadap versi.

(1) Untuk mendukung penyebaran berdampingan dari berbagai versi aplikasi (Anda dapat melakukan ini dengan Clickonce, misalnya). Ada kemungkinan untuk versi aplikasi yang berbeda untuk menyimpan pengaturan yang berbeda.

(2) Saat Anda mengupgrade aplikasi, kelas pengaturan mungkin telah diubah dan mungkin tidak kompatibel dengan apa yang disimpan, yang dapat menyebabkan masalah.

Namun demikian, kami telah mempermudah peningkatan pengaturan dari versi aplikasi sebelumnya ke yang terbaru. Cukup panggil ApplicationSettingsBase.Upgrade () dan itu akan mengambil pengaturan dari versi sebelumnya yang cocok dengan versi kelas saat ini dan menyimpannya di file user.config versi saat ini. Anda juga memiliki opsi untuk mengganti perilaku ini baik di kelas pengaturan Anda atau dalam implementasi penyedia Anda.

T: Oke, tapi bagaimana saya tahu kapan harus menelepon Upgrade?

J: Pertanyaan bagus. Di Clickonce, ketika Anda menginstal versi baru aplikasi Anda, ApplicationSettingsBase akan mendeteksinya dan secara otomatis meningkatkan pengaturan untuk Anda pada saat pengaturan dimuat. Dalam kasus non-Clickonce, tidak ada peningkatan otomatis - Anda harus menelepon Tingkatkan sendiri. Berikut ini satu ide untuk menentukan kapan harus memanggil Upgrade:

Miliki pengaturan boolean yang disebut CallUpgrade dan berikan nilai default true. Saat aplikasi Anda dimulai, Anda dapat melakukan sesuatu seperti:

if (Properties.Settings.Value.CallUpgrade)
{
   Properties.Settings.Value.Upgrade();
   Properties.Settings.Value.CallUpgrade = false;    
}

Ini akan memastikan bahwa Upgrade () hanya dipanggil saat pertama kali aplikasi dijalankan setelah versi baru di-deploy.

Saya tidak percaya sedetik pun bahwa itu benar-benar bisa berfungsi - tidak mungkin Microsoft menyediakan kemampuan ini, tetapi metodenya ada di sana.

Ian Boyd
sumber
3
INI BENAR-BENAR BERHASIL! Saya hanya menggunakan if(CallUpgrade) { Upgrade(); }pernyataan sederhana .
Anthony Mastrean
@Ian Boyd: Saya suka ide ini dan saya sangat senang memiliki solusi potensial namun saya bingung tentang satu hal. Saya tidak memiliki Properties.Settings.Value Saya memiliki Properties.Settingsbagian tetapi apakah saya melewatkan sesuatu atau apakah itu khusus untuk Anda?
Refraktasi Paladin
8
Ini berfungsi dengan baik, tetapi saya mengingatkan pembaca bahwa jalur konfigurasi hingga tetapi tidak termasuk nomor versi harus sama. yaitu lihat jawaban @ Amr. mis. jika versi baru aplikasi diluncurkan dari jalur file yang berbeda dari versi sebelumnya, maka Upgradetidak berfungsi.
Stephen Swensen
1
@RefractedPaladin ituProperties.Settings.Default.Upgrade()
Stephen Swensen
5
Jangan lupa untuk menambahkan Properties.Settings.Default.Save();setelah mengubahnya menjadi false :-)
Jeff
32

File user.config disimpan di

c:\Documents and Settings>\<username>\[Local Settings\]Application Data\<companyname>\<appdomainname>_<eid>_<hash>\<verison>

<c:\Documents and Settings>adalah direktori data pengguna, baik non-roaming (Pengaturan Lokal di atas) atau roaming.
<username>adalah nama pengguna.
<companyname>adalah nilai CompanyNameAttribute, jika tersedia. Jika tidak, abaikan elemen ini.
<appdomainname>adalah AppDomain.CurrentDomain.FriendlyName. Ini biasanya default ke nama .exe.
<eid>adalah URL, StrongName, atau Path, berdasarkan bukti yang tersedia untuk hash.
<hash>adalah bukti hash SHA1 yang dikumpulkan dari CurrentDomain, dengan urutan preferensi berikut:
1. StrongName
2. URL:
Jika tidak satu pun tersedia, gunakan jalur .exe.
<version>adalah pengaturan AssemblyInfo AssemblyVersionAttribute.

Penjelasan lengkap ada di sini http://msdn.microsoft.com/en-us/library/ms379611.aspx

Amr
sumber
4

(Saya akan menambahkan ini sebagai komentar pada jawaban @Amr, tetapi saya belum memiliki cukup perwakilan untuk melakukannya.)

The info di artikel MSDN sangat jelas dan tampaknya masih berlaku. Namun gagal menyebutkan bahwa hash SHA1 dituliskan basis 32 dikodekan, bukan basis 16 yang lebih khas.

Saya yakin algoritme yang digunakan diimplementasikan ToBase32StringSuitableForDirName, yang dapat ditemukan di sini di Sumber Referensi Microsoft .

JulianRendell
sumber