SmartAssembly 8

Copying files and dependencies after build

To use SmartAssembly you typically need to select an assembly to be protected (input assembly) and choose a path to which the final protected assembly will be saved (output assembly).

However, as you may expect, your assembly will still need certain files such as dependencies, resources, or configuration files, to be executed.

In this document you'll learn how to set up SmartAssembly to copy the required files automatically after build.

Introduction

For the purposes of the examples described in this document, let's assume you have a ./bin/Debug/ directory with the following contents:

(folders en and fr contain a Dependency.resources.dll file)

Let's also assume your SmartAssembly project is setup to protect MyApplication.exe, and merge MyLicensingLibrary.dll into it. The destination file is set to ./bin/protected/MyApplication.exe.

In this scenario, after building the SmartAssembly project, the output folder will have the following contents:

At this stage the protected application may not work properly when executed from within the output folder, because it lacks its dependencies and configuration files.

Note that .deps.json.runtimeconfig.json, and .runtimeconfig.dev.json files are always copied after build when building a .NET Core or .NET Standard or .NET 5+ assembly, independent of the options above.

Option 1 — copy dependencies, resources, and .config files

To copy main assembly's config file and also its dependencies (except merged and embedded), along with their config files, use the command-line /copyDependencies argument:

SmartAssembly.com /edit MyApplication.saproj /copyDependencies=true



If you open your SmartAssembly project file in a text editor you'll notice a new <CopyDependencies Enabled="1"> element was added within the <Options> node:

<SmartAssemblyProject ProjectId="{1ff3c572-c94e-475a-8802-3f23db3da28c}" Version="2.0">
    <MainAssemblyFileName>./bin/Debug/MyApplication.exe</MainAssemblyFileName>
    <Configuration Name="Release">
        <Destination DestinationFileName="./bin/protected/MyApplication.exe" />
        <Options>
            <CopyDependencies Enabled="1" />
            ...
        </Options>
        <Assemblies>
            ...
        </Assemblies>
    </Configuration>
</SmartAssemblyProject>

You can further configure the behavior by specifying attributes on the <CopyDependencies> option node:

AttributeDescription
Enabled

When 1, not-merged and not-embedded dependencies of the input assembly will be copied after build. Also, files described by the Configs/Satellites/NativeAssemblies/RuntimeAssemblies attributes will be copied (unless they're set to 0).

When 0, no additional file is copied after build.

When not defined, defaults to 0.

Optional attributes (only applicable when Enabled="1"):
Configs

When 1, configuration files of the input assembly and its dependencies will be copied after build (e.g. MyApplication.exe.config or Dependecy.dll.config).

When 0, configuration files will not be copied.

When not defined, defaults to 1.

Satellites

When 1, resource assemblies will be copied after build (e.g. MyApplication.resources.dll or Dependency.resources.dll).

When 0, resource assemblies will not be copied.

When not defined, defaults to 1.

NativeAssemblies

Only applicable to .NET Core, .NET Standard and .NET 5+ assemblies.

When 1, native dependencies defined in the input assembly's .deps.json file will be copied after build.

When 0, native assemblies will not be copied.

When not defined, defaults to 1.

RuntimeAssemblies

Only applicable to .NET Core, .NET Standard and .NET 5+ assemblies.

When 1, runtime dependencies defined in the input assembly's .deps.json file will be copied after build.

When 0, runtime assemblies will not be copied.

When not defined, defaults to 1.

Now, when you build the project, MyApplication.exe will be protected, MyLicensingLibrary.dll will be merged into it, and all required dependencies will be copied along with their .config files:

Note that MyLicensingLibrary.dll file was not copied. It was merged into the input assembly and is no longer needed.

Also note that additional files sample.config and some_configuration.json were not copied. That's because they're not directly associated with the input assembly nor its dependencies. Follow the instruction below (Option 2) to learn how to copy these files.

Option 2 — copy other files

To specify additional files you wish to be copied after buildedit your SmartAssembly project using the command line by using the /copyFiles argument:

SmartAssembly.com /edit MyApplication.saproj "/copyFiles=./bin/Debug/sample.config;./bin/Debug/some_configuration.json"


This will add the <AfterBuild> section to the project file (that you might as well add yourself manually, instead of using the command line), for example:

<SmartAssemblyProject ProjectId="{1ff3c572-c94e-475a-8802-3f23db3da28c}" Version="2.0">
    <MainAssemblyFileName>./bin/Debug/MyApplication.exe</MainAssemblyFileName>
    <Configuration Name="Release">
        <Destination DestinationFileName="./bin/protected/MyApplication.exe" />
        <AfterBuild>
            <CopyFiles>
                <File>./bin/Debug/sample.config</File>
                <File>./bin/Debug/some_configuration.json</File>
            </CopyFiles>
        </AfterBuild>
        <Options>
            ...
        </Options>
        <Assemblies>
            ...
        </Assemblies>
    </Configuration>
</SmartAssemblyProject>

All paths are relative to the project file and the files you want to copy to the output directory must exist within the input directory.


Optionally, for each <File> node you can specify the behavior for when the file already exists in the output directory, for example:

ExampleDescription
<File Overwrite="Always">

Always copies the file. If it already exists in the output directory, it gets overwritten.

This is a default behavior when Overwrite attribute is not specified.

<File Overwrite="IfNewer">Copies the file if it doesn't already exist in the output directory or if the file that already exists in the output directory has an older modification time than the one to be copied.
<File Overwrite="Never">Only copies the file if it doesn't already exist in the output directory.

Summary

Now, if you followed instructions for Option 1 and Option 2, the output folder will look like the following:

Note that MyLicensingLibrary.dll file was not copied. It was merged into the input assembly and is no longer needed.


Didn't find what you were looking for?