คุณจะเก็บการตั้งค่า user.config ข้ามแอสเซมบลีเวอร์ชันต่าง ๆ ใน. net ได้อย่างไร


146

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

ฉันจะคงการตั้งค่าเดิมไว้ได้อย่างไรเมื่ออัปเกรดเวอร์ชันเนื่องจากการใช้ไฟล์ ini หรือรีจิสทรีดูเหมือนจะหมดกำลังใจ

เมื่อเราใช้ Clickonce ดูเหมือนว่าจะสามารถจัดการกับสิ่งนี้ได้ดังนั้นจึงดูเหมือนว่าจะสามารถทำได้ แต่ฉันไม่แน่ใจว่าจะทำอย่างไร



ไม่นั่นหมายถึงค่าเริ่มต้นที่จะไม่ตรวจสอบไฟล์ในการควบคุมเวอร์ชัน (หรือดังนั้นฉันรวบรวม) นี่คือเกี่ยวกับการตั้งค่าเฉพาะของผู้ใช้ (Windows) สำหรับผู้ใช้ปลายทาง
Davy8

เพียงคำถามที่ฉันต้องการขอบคุณ :)
Binary Worrier

ฉันโพสต์วิธีแก้ปัญหาที่เป็นไปได้ในชุดข้อความต่อไปนี้: stackoverflow.com/a/47921377/3223783หวังว่าจะช่วยได้!
dontbyteme

ฉันโพสต์วิธีแก้ปัญหาที่เป็นไปได้ในชุดข้อความนี้ หวังว่าจะช่วย!
dontbyteme

คำตอบ:


236

ApplicationSettingsBase มีวิธีการอัปเกรดซึ่งจะย้ายการตั้งค่าทั้งหมดจากเวอร์ชันก่อนหน้า

ในการเรียกใช้การผสานเมื่อใดก็ตามที่คุณเผยแพร่แอปพลิเคชันรุ่นใหม่ของคุณคุณสามารถกำหนดแฟล็กบูลีนในไฟล์การตั้งค่าของคุณซึ่งเป็นค่าเริ่มต้นที่เป็นจริง ตั้งชื่อเป็นUpgradeRequiredหรือสิ่งที่คล้ายกัน

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

if (Settings.Default.UpgradeRequired)
{
    Settings.Default.Upgrade();
    Settings.Default.UpgradeRequired = false;
    Settings.Default.Save();
}

อ่านข้อมูลเพิ่มเติมเกี่ยวกับวิธีการอัพเกรดที่MSDN GetPreviousVersionนอกจากนี้ยังอาจจะคุ้มค่าดูถ้าคุณต้องการที่จะทำบางอย่างกลมกลืนที่กำหนดเอง


2
คำถามเล็ก ๆ น้อย ๆ สิ่งที่ถือว่าเป็นรุ่นใหม่ ส่วนใดของหมายเลขชิ้นส่วน 4 ฉันใช้ ClickOnce แล้วสัตว์อื่นล่ะ
Paladin หักเห

4
สิ่งที่ประเภทของการตั้งค่าควรUpgradeRequiredเป็นอย่างไร appSettings, userSettingsหรือapplicationSettings? เป็นการตั้งค่าของผู้ใช้ในการตั้งค่าการตั้งค่าเมื่อครั้งแรกที่มันถูกเปลี่ยนเป็นเท็จมันจะไม่เป็นจริงอีกครั้ง เวอร์ชันใหม่จะไม่รีเซ็ตUpgradeRequiredนั้นกลับเป็น True
dialex

4
@dialex ต้องเป็นการตั้งค่าผู้ใช้ การตั้งค่าประเภทแอปพลิเคชันเป็นแบบอ่านอย่างเดียว หมายเลขเวอร์ชันใหม่ทำให้การตั้งค่ารีเซ็ตเนื่องจากการตั้งค่าถูกเก็บไว้ในพา ธ เฉพาะเวอร์ชัน
Leonard Thieu

4
ฉันคิดว่าฉันตอบคำถามของตัวเอง หากมีไฟล์การตั้งค่าเวอร์ชันก่อนหน้ามันจะคัดลอกค่าลงในเวอร์ชันใหม่ล่าสุดทุกครั้งที่แอปเริ่มทำงานอาจไม่ใช่สิ่งที่คุณต้องการ!
Hugh Jeffner

1
ฉันรู้สึกประหลาดใจเล็กน้อยที่นี่ไม่ใช่แค่พฤติกรรมเริ่มต้นเท่านั้น หากการตั้งค่าของแอปพลิเคชั่นเป็นโมฆะเมื่อเริ่มต้นและพบการตั้งค่าเครือก่อนหน้านี้มันจะโหลดขึ้นมา
SteveCinq

3

ฉันรู้ว่ามันใช้เวลาไม่นาน ... ในแอป winforms เพียงโทรหาMy.Settings.Upgrade()คุณก่อนที่จะโหลด สิ่งนี้จะได้รับการตั้งค่าล่าสุดไม่ว่าจะเป็นรุ่นปัจจุบันหรือรุ่นก่อนหน้า


2

นี่คืองานวิจัยของฉันในกรณีที่คนอื่นประสบปัญหากับการตั้งค่าการย้ายข้อมูลที่ถูกเปลี่ยน / ลบ ปัญหาพื้นฐานคือGetPreviousVersion()ไม่สามารถใช้งานได้หากคุณเปลี่ยนชื่อหรือลบการตั้งค่าในแอปพลิเคชันเวอร์ชันใหม่ของคุณ ดังนั้นคุณต้องเก็บการตั้งค่าไว้ในSettingsชั้นเรียนของคุณแต่เพิ่มคุณสมบัติ / สิ่งประดิษฐ์ลงไปเล็กน้อยเพื่อที่คุณจะไม่ได้ใช้มันในรหัสอื่น ๆ โดยไม่ได้ตั้งใจทำให้มันล้าสมัย ตัวอย่างการตั้งค่าที่ล้าสมัยจะมีลักษณะเช่นนี้ใน VB.NET (สามารถแปลเป็น C # ได้อย่างง่ายดาย):

<UserScopedSetting(),
DebuggerNonUserCode(),
DefaultSettingValue(""),
Obsolete("Do not use this property for any purpose. Use YOUR_NEW_SETTING_NAME instead."),
NoSettingsVersionUpgrade()>
Public Property OldSettingName() As String
  Get
    Throw New NotSupportedException("This property is obsolete")
  End Get
  Set
    Throw New NotSupportedException("This property is obsolete")
  End Set
End Property

ตรวจสอบให้แน่ใจว่าคุณเพิ่มคุณสมบัตินี้ในเนมสเปซ / คลาสเดียวกันที่มีการตั้งค่าแอปพลิเคชันของคุณ ใน VB.NET คลาสนี้มีชื่อMySettingsและพร้อมใช้งานในMy namespace คุณสามารถใช้ฟังก์ชั่นการเรียนบางส่วนเพื่อป้องกันการตั้งค่าที่ล้าสมัยจากการมิกซ์กับการตั้งค่าปัจจุบันของคุณ

เครดิตทั้งหมดสำหรับ jsharrison สำหรับการโพสต์บทความที่ยอดเยี่ยมเกี่ยวกับปัญหานี้ คุณสามารถอ่านรายละเอียดเพิ่มเติมได้ที่นี่


1

นี่คือความแตกต่างของโซลูชั่นที่นำเสนอในที่นี้ซึ่งสรุปการอัพเกรดตรรกะลงในคลาสนามธรรมที่คลาสการตั้งค่าสามารถได้รับมา

โซลูชันที่เสนอบางตัวใช้แอตทริบิวต์ DefaultSettingsValue เพื่อระบุค่าที่ระบุเมื่อไม่ได้โหลดการตั้งค่าก่อนหน้านี้ การตั้งค่าของฉันคือใช้ประเภทที่มีค่าเริ่มต้นระบุสิ่งนี้ เป็นโบนัส DateTime หรือไม่? เป็นข้อมูลการแก้ไขข้อบกพร่องที่เป็นประโยชน์

public abstract class UserSettingsBase : ApplicationSettingsBase
{
    public UserSettingsBase() : base()
    {
        // Accessing a property attempts to load the settings for this assembly version
        // If LastSaved has no value (default) an upgrade might be needed
        if (LastSaved == null)
        {
            Upgrade();
        }
    }

    [UserScopedSetting]
    public DateTime? LastSaved
    {
        get { return (DateTime?)this[nameof(LastSaved)]; }
        private set { this[nameof(LastSaved)] = value; }
    }

    public override void Save()
    {
        LastSaved = DateTime.Now;
        base.Save();
    }
}

สืบทอดมาจาก UserSettingsBase:

public class MySettings : UserSettingsBase
{
    [UserScopedSetting]
    public string SomeSetting
    {
        get { return (string)this[nameof(SomeSetting)]; }
        set { this[nameof(SomeSetting)] = value; }
    }

    public MySettings() : base() { }
}

และใช้มัน:

// Existing settings are loaded and upgraded if needed
MySettings settings = new MySettings();
...
settings.SomeSetting = "SomeValue";
...
settings.Save();

0

หากการเปลี่ยนแปลงของคุณกับผู้ใช้การตั้งค่าเสร็จสิ้นโดยทางโปรแกรมวิธีการเกี่ยวกับการรักษาสำเนา (เพียง) การปรับเปลี่ยนผู้ใช้การตั้งค่าในไฟล์แยกต่างหากเช่น user.customized.settings?

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

แก้ไข: ฉันอ่านเร็วเกินไปในส่วน "แม่นยำยิ่งขึ้น" เกี่ยวกับแอสเซมบลีรุ่นทำให้ผู้ใช้ใหม่การตั้งค่าที่จะติดตั้งลงในไดเรกทอรีเฉพาะรุ่นใหม่ ดังนั้นความคิดข้างต้นอาจไม่ช่วยให้คุณ แต่อาจเตรียมอาหารสำหรับความคิด


0

นี่คือวิธีที่ฉันจัดการ:

public virtual void LoadSettings(ServiceFileFormBaseSettings settings = null, bool resetSettingsToDefaults = false)
{
    if (settings == null)
            return;

    if (resetSettingsToDefaults)
        settings.Reset();
    else
    {
        settings.Reload();

        if (settings.IsDefault)
            settings.Upgrade();
    }

    this.Size = settings.FormSize;

}

และในคลาสการตั้งค่าฉันกำหนดคุณสมบัติ IsDefault:

// SaveSettings always sets this to be FALSE.
// This will have the default value TRUE when first deployed, or immediately after an upgrade.
// When the settings exist, this is false.
//
[UserScopedSettingAttribute()]
[DefaultSettingValueAttribute("true")]
public virtual bool IsDefault
{
    get { return (bool)this["IsDefault"]; }
    set { this["IsDefault"] = value; }
}

ใน SaveSettings ฉันตั้ง IsDefault เป็น false:

public virtual void SaveSettings(ServiceFileFormBaseSettings settings = null)
{
    if (settings == null) // ignore calls from this base form, if any
        return;

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