その1 プロジェクトファイルにコマンドを追加
VBプロジェクトファイルの
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
のあとに以下の文字列を挿入します
<Target Name="AfterResolveReferences">
<ItemGroup>
<EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
<LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Target>
その2 EXEからアセンブリをロードするコードを追加
以下のコードをソースファイルにしてプロジェクトに追加してください。
startup.vb
<System.STAThreadAttribute(), _
System.Diagnostics.DebuggerNonUserCodeAttribute()> _
Public Sub Main()
AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf OnResolveAssembly
Dim app As Application = New Application()
Dim oMain As New MainWindow
app.Run(oMain)
End Sub
Private Function OnResolveAssembly(sender As Object, args As ResolveEventArgs) As System.Reflection.Assembly
Dim executingAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
Dim assemblyName As New System.Reflection.AssemblyName(args.Name) Dim path As String = assemblyName.Name + ".dll"
If assemblyName.CultureInfo.Equals(System.Globalization.CultureInfo.InvariantCulture) = False Then
path = [String].Format("{0}\{1}", assemblyName.CultureInfo, path)
End If
Using stream As System.IO.Stream = executingAssembly.GetManifestResourceStream(path)
If stream Is Nothing Then
Return Nothing
End If
Dim assemblyRawBytes As Byte() = New Byte(stream.Length - 1) {}
stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length)
Return System.Reflection.Assembly.Load(assemblyRawBytes)
End Using
End Function
End Module
その3 プロジェクト設定を変更
プロジェクト設定を変更して、スタートアップオブジェクトをその2で追加したソースに変更する。
すべて終了したらビルドすればEXE単独で起動できるようになります。
ただし、WPFToolkitのグラフのようにDLLからDLLの関数を呼んでいたりすると動かない場合があるので100%とはいきませんが99%くらいはこれでいけます。
WPFプロジェクトじゃなくても使えるので意外に便利です。
今回の記事は次のサイトの日本語訳だったりする
DLL embedding in a WPF or WinForm application (VB.NET and C#)