exeと同階層にあるファイルをサブフォルダにまとめたい
Q&A
Closed
解決したいこと
Visual Studio 2022でWindowsフォームアプリを作っています。
プロジェクトの発行をすると、出力フォルダ(今回はpublish_folderとします)にexeやdllなどが出力されます。
publish_folder
└appX.exe
└appX.dll
└aaa.dll
└bbb.dll
└appX.dll.config
実行時、ユーザーはexeをダブルクリックして起動しますが、このままだとexeがほかのファイルに埋もれてしまって見つけにくいです。(上のイメージはかなり簡略化しており。実際のファイルの数は非常に多いです。)
そこで、フォルダを開けばexeがすぐに見つかるよう、exe以外のファイルをサブフォルダにまとめてしまいたいと考えています。
publish_folder
└appX.exe
└bin
└appX.dll
└aaa.dll
└bbb.dll
└appX.dll.config
前提・環境
- Visual Studio 2022
- Windows Form App
- .NET6.0
- exeにdllを全て埋め込んでしまう単一ファイルでの発行も可能ですが、この方法は使わずに単にフォルダ分けで対応したいと考えています。
- installerを作ればそもそもユーザーにアプリケーションディレクトリを触らせずに済みますが、今回はそのまま使わせるケースを想定しています。
自分で試したこと
しかし単にサブフォルダを作って移動しただけでは当然ですがexeから必要なファイルが参照できず起動できません。
いくつかのサイトを参考に
- 参考1 https://qiita.com/float-on-mk-9/items/166ccb7a1fed53783a0e
- 参考2 https://dobon.net/vb/dotnet/programing/appconfigfile.html
- 参考3 https://learn.microsoft.com/ja-jp/dotnet/framework/configure-apps/file-schema/runtime/probing-element
以下の通り方針を立てました。
- appX.exe.configからbinフォルダを参照させるよう<probing privatePath="bin"/> を追記
- appX.dll.configからbinフォルダを参照させるよう<probing privatePath="bin"/> を追記
- appX.exe.configを新規作成してbinフォルダを参照させるよう<probing privatePath="bin"/> を追記
どれもうまくいきませんでした。
appX.exe.configからbinフォルダを参照させる
そもそもappX.exe.configが存在しません。ソリューションエクスプローラー上でapp.configは作っています。中身もいろいろ書いて使っています。(ユーザー設定もアプリケーション設定も)
参考2によると、このapp.configからappX.exe.configが生成されるそうですが、発行しても生成されません。代わりにappX.dll.configが生成され、こちらにapp.configの中身が反映されています。
appX.dll.configからbinフォルダを参照させる
appX.exe.configがないならappX.dll.configに書くしかないかと考えこちらに<probing privatePath="bin"/> を追記しました。
(ちなみに、<probing privatePath="bin"/>の親要素であるruntimeとassemblyBinding も追記しました。)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=aaa" >
<section name="appX.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=aaa" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=aaa" >
<section name="appX.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=aaa" requirePermission="false" />
</sectionGroup>
</configSections>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin" />
</assemblyBinding>
</runtime>
<connectionStrings />
<userSettings>
<appX.My.MySettings>
<setting name="path_database_folder" serializeAs="String">
<value />
</setting>
</appX.My.MySettings>
</userSettings>
<applicationSettings>
<appX.My.MySettings>
<setting name="is_development" serializeAs="String">
<value>False</value>
</setting>
</appX.My.MySettings>
</applicationSettings>
</configuration>
同時に、appX.dllとappX.dll.configをpublish_folder直下に移動しました。
publish_folder
└appX.exe
└appX.dll
└appX.dll.config
└bin
└aaa.dll
└bbb.dll
しかしこれでもうまくいかず、.NET Runtimeをダウンロードするように指示されます。
runtimeはbinフォルダに入れています(配置モードを自己完結モードにしている)。
appX.exeからappX.dllを参照してからappX.dllからruntimeを探してくれればよいのですが、そうではなくappX.exeから探すので見つからないよと言われるのかなと思いました。
ではruntimeもpublish_folder直下に上げたらよいかと思わなくもないですが、どれを動かせばよいのかわからないのと、動かしたらdllの参照対象から外れてしまったりするんじゃないかとも思われ、やりたくありません。そもそも、もともとのやりたいことがexeをほかのファイルに埋もれさせないことだったので、その目的から遠ざかってしまいます。
appX.exe.configを新規作成してbinフォルダを参照させるよう<probing privatePath="bin"/> を追記
紆余曲折を経ましたが、やはりappX.exe.configからbinフォルダを参照するしかないと思いました。
app.exe.configが自動生成されないなら仕方ないと自分で作り、以下のように記載しました。probing要素を書くために必要な情報だけ書いたものです。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin" />
</assemblyBinding>
</runtime>
</configuration>
これをpublish_folder直下に置きました。現状のフォルダ構造は以下の通りです。
publish_folder
└appX.exe
└appX.exe.config
└bin
└aaa.dll
└bbb.dll
└appX.dll
└appX.dll.config
この状態でappX.exeをダブルクリックしても何も起きません。
やりたいことはexe以外をサブフォルダにまとめたいというよくありそうかつ簡単そうなことなのですが、万策尽きました。方法をご存じの方、ご教示いただけますと幸いです。
何卒よろしくお願いいたします。