3

実行可能ファイル内にリソースとして埋め込もうとしている.dllがあります。次の2つの質問は多少役に立ちますが、完全な助けにはなりません。

別のアセンブリ内にアセンブリを埋め込む

これは書かれたとおりに機能していないようです。args.Nameは記述どおりに使用できませんが、修正された場合でも、プログラムは.dllが見つからないことを通知し、アセンブリが正しくロードされていないことを示します。

コンパイルされた実行可能ファイルへのDLLの埋め込み

との答えの1つのリンク:

http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/

ただし、私のプロジェクトには「App.xaml*」ファイルはありません。WPFを使用していません。実行可能ファイルにWinFormsを使用しています(実行可能ファイルの性質上、変更は実際にはオプションではありません)。

したがって、クラスライブラリを実行可能ファイルにリソースとして埋め込み、埋め込まれたリソースの外部に.dllファイルを必要とせずに、リソースからその.dllをロードするための完全な手順を探しています。

たとえば、「App.xaml」ファイルをWinFormsプロジェクトに追加するのは実用的でしょうか、それとも私が気付いていない否定的な相互作用があるのでしょうか。

ありがとう。

編集:これは私が現在使用しているものです:

/// <summary>
/// Stores the very few things that need to be global.
/// </summary>
static class AssemblyResolver
{
    /// <summary>
    /// Call in the static constructor of the startup class.
    /// </summary>
    public static void Initialize( )
    {
        AppDomain.CurrentDomain.AssemblyResolve +=
            new ResolveEventHandler( Resolver ) ;
    }


    /// <summary>
    /// Use this to resolve assemblies.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public static Assembly Resolver( object sender, ResolveEventArgs args )
    {
        Assembly executingAssembly = Assembly.GetExecutingAssembly( ) ;
        if ( args.Name == null )
            throw new NullReferenceException(
                "Item name is null and could not be resolved."
            ) ;
        if ( !executingAssembly.GetManifestResourceNames().Contains( 
                "Many_Objects_Display.Resources." +
                new AssemblyName( args.Name ).Name.Replace( ".resources", ".dll" ) )
            )
            throw new ArgumentException( "Resource name does not exist." ) ;

        Stream resourceStream =
            executingAssembly.GetManifestResourceStream(
                "Many_Objects_Display.Resources." +
                new AssemblyName( args.Name ).Name.Replace( ".resources", ".dll" )
            ) ;
        if ( resourceStream == null )
            throw new NullReferenceException( "Resource stream is null." ) ;
        if ( resourceStream.Length >  104857600)
            throw new ArgumentException(
                "Exceedingly long resource - greater than 100 MB. Aborting..."
            ) ;

        byte[] block = new byte[ resourceStream.Length ] ;
        resourceStream.Read( block, 0, block.Length ) ;

        Assembly resourceAssembly = Assembly.Load( block ) ;
        if ( resourceAssembly == null )
            throw new NullReferenceException( "Assembly is a null value." ) ;
        return resourceAssembly ;
    }
}
4

1 に答える 1

5

コードをメインのエントリポイントに配置する必要があります。このようなもの:

class Program
{
  static Program()
  {
     AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
  }

  static void Main(string[] args)
  {
    // what was here is the same
  }

  static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
  {
      // the rest of sample code
  }

}

App.xamlファイルをWindowsフォームアプリケーションに追加するだけでは不十分です。

また、のサンプルコードCurrentDomain_AssemblyResolveは奇妙なので、最初にこのコードを試してみます。私はそれをテストしていませんが、それは私が以前に使用したコードのように見えます。

于 2012-06-07T07:38:54.500 に答える