Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【VB.NET】Windows Formで設定値をDebugとReleaseで切り替えたい

More than 1 year has passed since last update.

タイトル通りのことをやりたかったけど、思ったより苦労したのでそのメモ。
Visual Studio 2017

失敗:ASP.NETのApp.configを切り替える機能を使う

ASP.NETではビルド構成に合わせてApp.configを切り替える機能があるが、Windows Formにはない。
検索すると、WindowsアプリでもASP.NETの機能を流用してconfigファイルを置き換える手段が見つかる。

App.configをビルドターゲットによって書き換える - Qiita

しかし、実際にやってみてもビルド後のconfigファイルが置き換わらない。
<appSettings>タグも「設定」関連のどちらも置き換わらず。

Settingsファイルを2つ作り、ビルド時に構成によって切り替えようとしたけど、それもダメだった。

<None Include="Settings.Debug.settings" Condition=" '$(Configuration)' == 'Debug' ">
  <Generator>SettingsSingleFileGenerator</Generator>
</None>
<None Include="Settings.Release.settings" Condition=" '$(Configuration)' == 'Release' ">
  <Generator>SettingsSingleFileGenerator</Generator>
</None>

condition属性が有効にならないし、ファイル名=クラス名になってしまうので置換になっていない。

プロジェクト直下にDebugとReleaseのフォルダを作成し、同じSettings1.settingsというファイルを作ってみたところ、お互いが競合してapp.configとsettingsファイルを上書きしあってしまう。

ビルド後スクリプトでconfigファイルの内容を置き換える

Visual Studioには、ビルド前、ビルド後に実行させたいことを指定できる。
方法: ビルド イベントを指定する (Visual Basic) - Visual Studio | Microsoft Docs

これを使い、ビルド後にconfigファイルを置き換える処理を自作した。

configファイルを用意する

オリジナルのApp.configと構成毎のconfigファイルを用意する。
04.png
3つ並ぶのが鬱陶しいなら、vbprojファイルをいじって、以下のようにできる。
05.png

vbprojファイル抜粋
<Content Include="App.config">
  <SubType>Designer</SubType>
</Content>
<Content Include="App.Debug.config">
  <DependentUpon>App.config</DependentUpon>
  <SubType>Designer</SubType>
</Content>
<Content Include="App.Release.config" >
  <DependentUpon>App.config</DependentUpon>
  <SubType>Designer</SubType>
</Content>

PowerShellでconfigファイルの内容を上書きする

.NETにはconfigファイルを読み書きするためのクラス等が用意されているが、「設定」の部分は扱えないようなので、普通のXMLファイルとして読み書きする。

appSettingsタグしか使用しないなら有用な方法。
PowerShellでアプリケーション構成ファイル(app.config)を読み書きする - しばたテックブログ

App.configをXMLファイルとして読み取り、以下で囲んだ部分を読み取って置き換える。
01.png

PowerShellに渡すパラメータとして、以下が必要:

  • オリジナルのApp.configのファイルパス
  • 置き換えたい内容が含まれているApp.configのファイルパス(App.Debug.configなど)
  • プロジェクト名 (MySettingsが定義されているタグ名にプロジェクト名が入っている)
サンプルスクリプト(一部)
Param($targetAppConfigPath, $sourceAppConfigPath, $outputPath, $projectName)

Add-Type -AssemblyName System.Configuration

if (!(Test-Path $targetAppConfigPath) -or !(Test-Path $sourceAppConfigPath)) {
    return
}

# ファイル読込
[xml]$targetAppConfig = Get-Content $targetAppConfigPath -Encoding UTF8
[xml]$sourceAppConfig = Get-Content $sourceAppConfigPath -Encoding UTF8

function main() {

    copySettings "configuration/applicationSettings/$projectName.My.MySettings"
    copySettings "configuration/userSettings/$projectName.My.MySettings"
    copyConnectionStrings "configuration/connectionStrings"
    copyAppConfigs "configuration/appSettings"

    $targetAppConfig.Save($outputPath)
}

PowerShellをプロジェクトに配置する

プロジェクト内にps1ファイルを置く。サンプルでは「BuildScripts」フォルダに置いた。
03.png

PowerShellをビルド後に実行する

プロジェクトのプロパティを開き、「コンパイル」タブの「ビルドイベント」を押す。

以下のコマンドを、ビルド後のコマンドに追加する。

powershell -NoProfile -ExecutionPolicy Unrestricted -file "$(ProjectDir)BuildScripts\ReplaceSettings.ps1" "$(ProjectDir)App.config" "$(ProjectDir)App.$(ConfigurationName).config" "$(TargetDir)$(TargetFileName).config" $(ProjectName)

通常、PowerShellを呼び出すときに-fileは無くても良いはずだが、ここでは付けないとエラーになる。

これで、出力フォルダには構成毎の設定値が出力されるようになる。

このスクリプトを使ったサンプルをGitHubに保管した。
https://github.com/vicugna-pacos/vbnet_separate_config

vicugna-pacos
SIerにいながら業務効率化などに関わっています。最近は自サイトに技術メモを書くようにしています。
https://vicugna-pacos.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away