기본적으로 문제는 어셈블리 버전이 변경 될 때마다 (즉, 사용자가 새 버전의 응용 프로그램을 설치할 때마다) 모든 설정이 기본값을 재설정하거나 더 정확하게 다른 버전의 폴더에 새 user.config 파일이 생성된다는 것입니다 이름으로 숫자)
ini 파일이나 레지스트리를 사용하지 않는 것처럼 보이기 때문에 버전을 업그레이드 할 때 어떻게 같은 설정을 유지할 수 있습니까?
우리가 Clickonce를 사용했을 때 이것을 처리 할 수있는 것처럼 보였으므로 그렇게 할 수 있어야하는 것처럼 보이지만 어떻게 해야할지 모르겠습니다.
답변
ApplicationSettingsBase에는 이전 버전의 모든 설정을 마이그레이션하는 Upgrade라는 메소드 가 있습니다.
새 버전의 응용 프로그램을 게시 할 때마다 병합을 실행하려면 설정 파일에서 기본값이 true 인 부울 플래그를 정의 할 수 있습니다. UpgradeRequired 또는 이와 유사한 이름을 지정하십시오 .
그런 다음 응용 프로그램 시작시 플래그가 설정되어 있는지 확인하고 설정되어 있으면 Upgrade 메소드를 호출 하고 플래그를 false로 설정 한 후 구성을 저장하십시오.
if (Settings.Default.UpgradeRequired)
{
Settings.Default.Upgrade();
Settings.Default.UpgradeRequired = false;
Settings.Default.Save();
}
MSDN 의 업그레이드 방법에 대해 자세히 알아보십시오 . GetPreviousVersion는 일부 사용자 정의 병합을 수행해야하는 경우도 가치가보고 될 수 있습니다.
답변
시간이 오래 걸렸습니다 … winforms 앱에서 불러 My.Settings.Upgrade()
오기 전에 전화하십시오 . 현재 버전이든 이전 버전이든 최신 설정을 가져옵니다.
답변
다른 사람이 변경 / 제거 된 설정을 마이그레이션하는 데 어려움을 겪고있는 경우에 대한 나의 연구는 다음과 같습니다. 기본 문제는 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
네임 스페이스 . 부분 클래스 기능을 사용하여 사용하지 않는 설정이 현재 설정과 섞이지 않도록 할 수 있습니다.
이 문제에 대한 훌륭한 기사 를 게시 해 주신 jsharrison에게 감사의 마음을 전 합니다. 거기에 대한 자세한 내용을 읽을 수 있습니다.
답변
다음은 업그레이드 논리를 설정 클래스에서 파생 될 수있는 추상 클래스로 캡슐화하는 여기에 제시된 솔루션의 변형입니다.
일부 제안 된 솔루션은 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();
답변
user.settings에 대한 변경이 프로그래밍 방식으로 수행되는 경우 user.settings에 대한 수정 사본을 별도의 파일 (예 : user.customized.settings)로 유지 관리하는 것은 어떻습니까?
user.settings에서도 수정 된 설정을 유지하고로드 할 수 있습니다. 그러나이 방법으로 최신 버전의 user.settings를 사용하여 최신 버전의 응용 프로그램을 설치하면 수정 된 설정을 새 user.settings로 다시 복사하여 계속 사용할 것인지 묻는 메시지를 표시 할 수 있습니다. 도매로 가져 오거나 더 좋아져 계속 사용할 설정을 사용자에게 요청할 수 있습니다.
편집 : 어셈블리 버전에 대한 “보다 정확한”부분을 너무 빨리 읽고 새 user.settings를 새 버전 별 디렉토리에 설치합니다. 따라서 위의 아이디어가 도움이되지는 않지만 생각할만한 음식을 제공 할 수 있습니다.
답변
이것이 내가 처리 한 방법입니다.
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();
}