ฉันสามารถควบคุมตำแหน่งของการตั้งค่าผู้ใช้. NET เพื่อหลีกเลี่ยงการสูญเสียการตั้งค่าในการอัปเกรดแอปพลิเคชันได้หรือไม่


104

ฉันกำลังพยายามปรับแต่งตำแหน่งของuser.configไฟล์ ขณะนี้มีการจัดเก็บแฮชและหมายเลขเวอร์ชัน

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

ฉันต้องการที่จะไม่เชื่อเรื่องพระเจ้ากับเวอร์ชันของแอปพลิเคชัน

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

สามารถทำได้หรือไม่? มีผลกระทบอย่างไร? ผู้ใช้จะสูญเสียการตั้งค่าจากเวอร์ชันก่อนหน้าหลังจากอัปเกรดหรือไม่


แม้ว่าคำตอบของ uzbonesจะให้ข้อมูลเกี่ยวกับตำแหน่งไฟล์ แต่ฉันเชื่อว่าIanนั้นถูกต้องมากกว่าในเรื่องการอัปเกรด
Anthony Mastrean

4
@AnthonyMastrean โดยส่วนตัวแล้วฉันคิดว่าการตั้งค่าที่สำคัญใด ๆ ไม่ควรพึ่งพาโครงสร้างพื้นฐานApplicationSettings ที่ให้ Microsoft ของฉัน Muxa ควรเก็บการตั้งค่าไว้ใน%AppData%\[CompanyName]/[ProductName]ที่ที่เราสามารถไว้วางใจได้ว่าจะยังคงอยู่
Ian Boyd

2
ไม่ต้องสงสัยเลยว่าประสบการณ์ต่อเนื่องของฉันกับแอปพลิเคชันในตัวและการตั้งค่าผู้ใช้นั้นแย่มาก ฉันแนะนำไฟล์ json ใน appdata หรือ programdata
Anthony Mastrean

คุณยังสามารถจัดเก็บการตั้งค่าของคุณในรีจิสทรี ดูstackoverflow.com/a/12127888/1273550สำหรับการใช้งานคลาสการตั้งค่าทางเลือก
Ravi Patel

คำตอบ:


39

ในการตอบคำถามแรกในทางเทคนิคคุณสามารถวางไฟล์ได้ทุกที่ที่คุณต้องการอย่างไรก็ตามคุณจะต้องเขียนโค้ดด้วยตัวเองเนื่องจากตำแหน่งเริ่มต้นที่ไฟล์จะไปเป็นตัวอย่างแรกจากสองตัวอย่างของคุณ ( ลิงค์วิธีทำเอง )

สำหรับคำถามที่สองขึ้นอยู่กับว่าคุณปรับใช้แอปพลิเคชันอย่างไร หากคุณปรับใช้ผ่าน. msi จะมีสองแฮชในคุณสมบัติของโปรเจ็กต์การตั้งค่า (ที่สร้างขึ้นจาก msi) 'รหัสอัพเกรด' และ 'รหัสผลิตภัณฑ์' สิ่งเหล่านี้กำหนดวิธีการติดตั้ง msi และหากอัพเกรดเขียนทับหรือติดตั้งข้างแอปพลิเคชันเดียวกันเวอร์ชันอื่น ๆ

ตัวอย่างเช่นหากคุณมีซอฟต์แวร์สองเวอร์ชันและมีรหัส 'อัพเกรด' ที่แตกต่างกันสำหรับ windows ซอฟต์แวร์เหล่านี้จะเป็นซอฟต์แวร์ที่แตกต่างกันโดยสิ้นเชิงไม่ว่าจะเป็นชื่ออะไรก็ตาม อย่างไรก็ตามหากรหัส 'อัพเกรด' เหมือนกัน แต่รหัส 'ผลิตภัณฑ์' แตกต่างกันเมื่อคุณพยายามติดตั้ง msi ตัวที่ 2 ระบบจะถามคุณว่าคุณต้องการอัปเกรดหรือไม่ซึ่งในเวลานั้นควรคัดลอกค่าจาก config เก่าเป็น config ใหม่ หากทั้งสองค่าเหมือนกันและหมายเลขเวอร์ชันไม่เปลี่ยนแปลงการกำหนดค่าใหม่จะอยู่ในตำแหน่งเดียวกับการกำหนดค่าเดิมและไม่ต้องทำอะไรเลย เอกสาร MSDN

ClickOnce แตกต่างกันเล็กน้อยเนื่องจากอิงจาก ClickOnce เวอร์ชัน # และเส้นทาง URL มากกว่าอย่างไรก็ตามฉันพบว่าตราบใดที่คุณยังคง 'เผยแพร่' ไปยังตำแหน่งเดิมแอปพลิเคชันเวอร์ชันใหม่จะยังคงใช้ config ที่มีอยู่ ( ลิงก์ไปยังวิธีที่ ClickOnce จัดการกับการอัปเดต )

ฉันยังรู้ว่ามีวิธีผสานการกำหนดค่าด้วยตนเองระหว่างการติดตั้ง msi โดยใช้สคริปต์การติดตั้งแบบกำหนดเอง แต่ฉันจำขั้นตอนที่ต้องทำไม่ได้แน่นอน ... (ดูลิงค์นี้สำหรับวิธีการทำกับเว็บ config)


รหัสอัปเกรดไม่ใช่รหัสที่ควรจะคงที่และรหัสผลิตภัณฑ์เป็นรหัสที่ควรเปลี่ยนระหว่างรุ่นหรือไม่? blogs.msdn.com/b/pusu/archive/2009/06/10/understand-msi.aspx
estanford

ดู๊! คุณพูดถูกไม่อยากจะเชื่อเลยว่าฉันได้สิ่งนั้นกลับมา (และใช้เวลา 2 ปีในการจับมัน) มันเหมือนกับการลงนาม robo ช่วงหนึ่งในอดีตของฉัน :(
uzbones

หมายความว่ามีเพียงผู้ใช้ที่ติดตั้งเท่านั้นที่ได้รับการอัปเกรดการตั้งค่าของเธอ?
Micha Wiedenmann

79

ฉันต้องการเพิ่มข้อความที่ยกมานี้เป็นข้อมูลอ้างอิงเมื่อฉันมีปัญหานี้ในอนาคต สมมติว่าคุณสามารถสั่งให้โครงสร้างพื้นฐาน ApplicationSettings คัดลอกการตั้งค่าจากเวอร์ชันก่อนหน้าได้โดยเรียกอัปเกรด :

Properties.Settings.Value.Upgrade();

จากบล็อกโพสต์คำถามที่พบบ่อยเกี่ยวกับการตั้งค่าไคลเอ็นต์ : ( เก็บถาวร )

ถาม: เหตุใดจึงมีหมายเลขเวอร์ชันในเส้นทาง user.config หากฉันปรับใช้แอปพลิเคชันเวอร์ชันใหม่ผู้ใช้จะไม่สูญเสียการตั้งค่าทั้งหมดที่บันทึกโดยเวอร์ชันก่อนหน้านี้ใช่หรือไม่

ตอบ: มีสาเหตุสองประการที่ทำให้พา ธ user.config ไวต่อเวอร์ชัน

(1) เพื่อรองรับการใช้งานแอปพลิเคชันเวอร์ชันต่างๆแบบเคียงข้างกัน (คุณสามารถทำได้ด้วย Clickonce เป็นต้น) เป็นไปได้ที่แอปพลิเคชันเวอร์ชันต่างๆจะบันทึกการตั้งค่าต่างๆไว้

(2) เมื่อคุณอัปเกรดแอปพลิเคชันคลาสการตั้งค่าอาจได้รับการเปลี่ยนแปลงและอาจเข้ากันไม่ได้กับสิ่งที่บันทึกไว้ซึ่งอาจทำให้เกิดปัญหาได้

อย่างไรก็ตามเราได้ทำให้การอัปเกรดการตั้งค่าจากแอปพลิเคชันเวอร์ชันก่อนหน้าเป็นเวอร์ชันล่าสุดเป็นเรื่องง่าย เพียงเรียก ApplicationSettingsBase.Upgrade ()และจะดึงการตั้งค่าจากเวอร์ชันก่อนหน้าที่ตรงกับเวอร์ชันปัจจุบันของคลาสและจัดเก็บไว้ในไฟล์ user.config ของเวอร์ชันปัจจุบัน คุณยังมีตัวเลือกในการลบล้างพฤติกรรมนี้ในคลาสการตั้งค่าของคุณหรือในการใช้งานผู้ให้บริการของคุณ

ถาม: โอเค แต่จะรู้ได้อย่างไรว่าเมื่อใดควรเรียกอัปเกรด

ตอบ: เป็นคำถามที่ดี ใน Clickonce เมื่อคุณติดตั้งแอปพลิเคชันเวอร์ชันใหม่ ApplicationSettingsBase จะตรวจพบและอัปเกรดการตั้งค่าให้คุณโดยอัตโนมัติเมื่อโหลดการตั้งค่าจุด ในกรณีที่ไม่ใช่ Clickonce จะไม่มีการอัปเกรดอัตโนมัติ - คุณต้องเรียกอัปเกรดด้วยตัวเอง นี่คือแนวคิดหนึ่งในการพิจารณาว่าเมื่อใดควรเรียกอัปเกรด:

ตั้งค่าบูลีนที่เรียกว่า CallUpgrade และให้ค่าเริ่มต้นเป็นจริง เมื่อแอปของคุณเริ่มทำงานคุณสามารถทำสิ่งต่อไปนี้

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

สิ่งนี้จะช่วยให้มั่นใจได้ว่ามีการเรียกใช้ Upgrade () ในครั้งแรกที่แอปพลิเคชันทำงานหลังจากใช้งานเวอร์ชันใหม่

ฉันไม่เชื่อสักวินาทีเดียวว่ามันสามารถใช้งานได้จริง - ไม่มีทางที่ Microsoft จะให้ความสามารถนี้ได้ แต่วิธีการนั้นก็เหมือนกัน


3
ทั้งหมดนี้ได้ผล! ฉันใช้if(CallUpgrade) { Upgrade(); }คำสั่งง่ายๆ
Anthony Mastrean

@Ian Boyd: ฉันชอบความคิดนี้และฉันรู้สึกท้อแท้กับการมีทางออกที่เป็นไปได้ แต่ฉันก็สับสนเกี่ยวกับสิ่งหนึ่ง ฉันไม่ได้มีProperties.Settings.Value ฉันมีProperties.Settingsส่วน แต่ฉันไม่มีอะไรหรือเป็นที่เฉพาะเจาะจงกับคุณ?
Refracted Paladin

8
สิ่งนี้ใช้งานได้ดี แต่ฉันเตือนผู้อ่านว่าเส้นทางของการกำหนดค่าถึง แต่ไม่รวมหมายเลขเวอร์ชันต้องเหมือนกัน คือดูคำตอบของ @ Amr เช่นหากมีการเปิดแอปเวอร์ชันใหม่จากเส้นทางไฟล์ที่แตกต่างจากเวอร์ชันก่อนหน้าก็Upgradeจะไม่ทำงาน
Stephen Swensen

1
@RefractedPaladin It'sProperties.Settings.Default.Upgrade()
Stephen Swensen

5
อย่าลืมเพิ่มProperties.Settings.Default.Save();หลังจากเปลี่ยนเป็น false :-)
Jeff

32

ไฟล์ user.config ถูกเก็บไว้ที่

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

<c:\Documents and Settings>คือไดเร็กทอรีข้อมูลผู้ใช้ไม่ว่าจะเป็นการโรมมิ่ง (Local Settings ด้านบน) หรือโรมมิ่ง
<username>คือชื่อผู้ใช้
<companyname>คือค่า CompanyNameAttribute ถ้ามี มิฉะนั้นให้เพิกเฉยต่อองค์ประกอบนี้
<appdomainname>คือ AppDomain.CurrentDomain.FriendlyName โดยปกติจะมีค่าเริ่มต้นเป็นชื่อ. exe
<eid>คือ URL, StrongName หรือเส้นทางตามหลักฐานที่มีอยู่ในแฮช
<hash>คือแฮช SHA1 ของหลักฐานที่รวบรวมจาก CurrentDomain ตามลำดับความต้องการดังต่อไปนี้:
1. StrongName
2. URL:
หากไม่มีทั้งสองอย่างนี้ให้ใช้เส้นทาง. exe
<version>คือการตั้งค่า AssemblyVersionAttribute ของ AssemblyInfo

ดูรายละเอียดทั้งหมดได้ที่นี่http://msdn.microsoft.com/en-us/library/ms379611.aspx


4

(ฉันจะเพิ่มสิ่งนี้เป็นความคิดเห็นในคำตอบของ @ Amr แต่ฉันยังไม่มีตัวแทนเพียงพอที่จะทำเช่นนั้น)

ข้อมูลในบทความ MSDNมีความชัดเจนมากและดูเหมือนจะยังคงใช้ อย่างไรก็ตามไม่ได้กล่าวถึงว่าแฮช SHA1 นั้นเขียนโดยเข้ารหัสฐาน 32 แทนที่จะเป็นฐาน 16 ทั่วไป

ผมเชื่อว่าอัลกอริทึมที่ใช้จะดำเนินการในToBase32StringSuitableForDirNameซึ่งสามารถพบได้ที่นี่ในไมโครซอฟท์ที่มาอ้างอิง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.