Expert Texture Home Contact me About Subscribe Digipede Connect on LinkedIn rwandering on Twitter rwandering on FriendFeed

rwandering.net

The blogged wandering of Robert W. Anderson

Renaming ASP.NET 2.0 Assemblies Redux

I have posted a bit on merging ASP.NET 2.0 (without aspnet_merge) and also on renaming ASP.NET 2.0 auto-named assemblies. My first solution on renaming was incomplete in that it would only work when there were no dependencies between the renamed assemblies.
This solution is correct and produces assemblies that properly get through Dotfuscator 3.0 / and actually run!   All of the code below are either nant targets or nant tasks.  These should be generally applicable (with the right properties assigned).

  1. Disassemble the assemblies with ildasm.
  2. Get the generated assembly name for a particular folder from a representative file (either an aspx or ascx).
  3. Replace the assembly name for all files (pages, controls, and the il) with a fixed name (e.g., “App_Web_Root”).
  4. Reassemble and rename the assembly’s DLL to the fixed name (using ilasm).

These targets assume the following properties are set:

ProjectPath
the path to your build project directory
ildasm
the full path to the ildasm executable
ilasm
the full path to the ilasm executable

The first part is disassembly (the most straight-forward part):

  
<!-- disassembles all App_Web assemblies to il -->
<target name="disassembleAspNet20Assemblies" >
    <foreach item="File" property="assembly">
      <in>
        <items basedir="${ProjectPath}\bin">
          <include name="App_Web*.dll" />
        </items>
      </in>
      <do>
        <exec program="${ildasm}" 
              workingdir="${ProjectPath}" 
              commandline=
               "/out=${assembly}.il /nobar /raweh /utf8 /quoteallnames /linenumbers ${assembly}" />
      </do>
    </foreach>
  </target>

The second part is to change the files to point to the new name:

  <!-- Renames a generated-assembly for ASP.NET 2.0 -->
  <!-- 'page' property is a representative page or control in the folder -->
  <!-- 'fixedAssemblyName' property is the new desired name of the assembly -->
  <target name="renameAspNet20Assembly">
    <loadfile property="loadedPage" file="${ProjectPath}\${page}" />
    <!-- get the assembly name from the representative page -->
    <regex pattern="(?'assembly'App_Web.+\s*)\042" input="${loadedPage}" />
    <!-- store the assembly name to fixed name mapping -->
    <property name="${assembly}" value="${fixedAssemblyName}"/>
    <!-- copy all of the pages (and il), replacing this 
          assembly name with the fixed name. -->
    <copy todir="${ProjectPath}/tmpBak" overwrite="true">
      <fileset basedir="${ProjectPath}">
        <include name="**\*.as?x" />
        <include name="**\*.dll.il" />
        <exclude name="tmpBak\**" />
      </fileset>
      <filterchain>
        <replacestring from="${assembly}" to="${fixedAssemblyName}" />
      </filterchain>
    </copy>
    <!-- copy them all back -->
    <copy todir="${ProjectPath}" overwrite="true">
      <fileset basedir="${ProjectPath}/tmpBak">
        <include name="**\*.as?x" />
        <include name="**\*.dll.il" />
      </fileset>
    </copy>
  </target>

Finally, the assemblies must be reassembled:

  <!--  Reassembles all the App_Web*il into a new fixedAssembly.  -->
  <!-- This requires that the il's assembly name exists as a property that maps to the new fixedAssembly name.-->
  <target name="reassembleAspNet20Assemblies" >
    <foreach item="File" property="assembly">
      <in>
        <items basedir="${ProjectPath}\bin">
          <include name="App_Web*.dll.il" />
        </items>
      </in>
      <do>
        <!-- get the old DLL name -->
        <property name="dllName" value="${path::get-file-name-without-extension(assembly)}"/>
       <!-- get the old assembly name -->
        <property name="assemblyOnly" value="${path::get-file-name-without-extension(dllName)}"/>
        <!-- get the new, fixed assembly name -->
        <property name="fixedAssemblyName" value="${property::get-value(assemblyOnly)}"/>
        <!-- reassemble -->
        <exec program="${ilasm}" workingdir="${ProjectPath}" 
                  commandline="/out=${ProjectPath}\bin\${fixedAssemblyName}.dll /dll /res=${ProjectPath}\bin\${dllName}.res ${assembly}" /> 
        </do>
    </foreach>
  </target>

Then, for each folder, I call the target like so:

    <!--Dissasemble the assemblies-->
    <call target="disassembleAspNet20Assemblies"/>
    <!-- use Administration.aspx as a proxy for the site's root directory -->
    <property name="page" value="Administration.aspx" />
    <property name="fixedAssemblyName" value="App_Web.ControlRoot" />
    <call target="renameAspNet20Assembly" />
    <!-- use Login.aspx as a proxy for the site's Secure directory -->
    <property name="page" value="Secure\Login.aspx" />
    <property name="fixedAssemblyName" value="App_Web.Secure" />
    <call target="renameAspNet20Assembly" />
    <!-- use Headers.ascx as a proxy for the site's Control directory -->
    <property name="page" value="Controls\Header.ascx" />
    <property name="fixedAssemblyName" value="App_Web.Controls" />
    <call target="renameAspNet20Assembly" />
    <!--reassemble the assemblies-->
    <call target="reassembleAspNet20Assemblies"/>

Tags: ,

    Trackback

No comments yet

Sorry, the comment form is closed at this time.