Skip to content

Commit

Permalink
* readme update
Browse files Browse the repository at this point in the history
* comments fixes
  • Loading branch information
preseverence committed May 6, 2019
1 parent 5fe5e64 commit 4d68d8a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 31 deletions.
6 changes: 3 additions & 3 deletions BrokenEvent.ILStrip.CLI/CommandLineOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ public string InputFilename
[Command("s", "Suppresses logging.", alias: "silent", isFlag:true)]
public bool Silent { get; set; }

[Command("e", "User defined entry point classes list to start analysis. Multiple values.", "MyAssembly.MyNamespace.MyClass")]
[Command("e", "User defined entry point classes list to start analysis. Multiple values.", "MyNamespace.MyClass")]
public List<string> EntryPoints { get; set; } = new List<string>();

[Command("h", "Hide public API with internal access modifier.", alias:"hide", isFlag:true)]
public bool HideApi { get; set; }

[Command("he", "Exclusions for -h option. Multiple values.", "MyAssembly.MyNamespace.MyClass")]
[Command("he", "Exclusions for -h option. Multiple values.", "MyNamespace.MyClass")]
public List<string> HideExclusions { get; set; } = new List<string>();

[Command("u", "Removes all unknown resources.", isFlag:true)]
public bool RemoveUnknownResources { get; set; }

[Command("re", "Resource exclusions for -u option. Multiple values.", "MyAssembly.MyNamespace.MyResource")]
[Command("re", "Resource exclusions for -u option. Multiple values.", "MyNamespace.MyResource")]
public List<string> ResourceExclusions { get; set; } = new List<string>();

[Command("we", "WPF Resource exclusions for -u option. Multiple values.", "resources/myresource.png")]
Expand Down
10 changes: 5 additions & 5 deletions BrokenEvent.ILStrip/ILStrip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,9 +476,9 @@ private bool CheckIfResourceShouldRemain(Resource resource, int i)
/// Gets the list of entry points to start the used classes search.
/// </summary>
/// <example>
/// <para>Use assembly-qualified names for classes.</para>
/// <para>Example of class: <c>MyAssembly.MyNamespace.MyClass</c></para>
/// <para>Example of nested class: <c>MyAssembly.MyNamespace.MyClass/MyNestedClass</c></para>
/// <para>Use namespace-qualified names for classes.</para>
/// <para>Example of class: <c>MyNamespace.MyClass</c></para>
/// <para>Example of nested class: <c>MyNamespace.MyClass/MyNestedClass</c></para>
/// </example>
public HashSet<string> EntryPoints
{
Expand All @@ -489,8 +489,8 @@ public HashSet<string> EntryPoints
/// Gets the list of exclusions to remain public if <see cref="MakeInternal"/> is used.
/// </summary>
/// <example>
/// <para>Use assembly-qualified names for classes.</para>
/// <para>Example of class: <c>MyAssembly.MyNamespace.MyClass</c></para>
/// <para>Use namespace-qualified names for classes.</para>
/// <para>Example of class: <c>MyNamespace.MyClass</c></para>
/// </example>
public HashSet<string> MakeInternalExclusions
{
Expand Down
91 changes: 68 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ C# Assembly unused classes/references/resources cleaner.
* Unused classes cleanup.
* Unused references clanup.
* Unused resources cleanup.
* Entry points support (points to start the usage anaylsis).
* Hide public API with **internal** access modifier.
* Custom entry points for types that don't refernced, but should remain.
* Hide private types with `internal` access modifier.
* WPF/BAML support.

## Usecase

The main goal is to filter .NET assemblies from unused classes after merging with [ILRepack](https://github.com/ststeiger/ILRepack). It will not optimize your code or somehow change its behavior, but will erase all that is not used in current assembly.
The main goal is to filter .NET assemblies from unused classes after merging with [ILRepack](https://github.com/ststeiger/ILRepack).
It will not optimize your code or somehow change its behavior, but will erase all that is not used in current assembly.

*ILStrip* works only on class level. If class is used somehow, all its members will remain even if they are not used.

Expand All @@ -36,12 +38,12 @@ ILStrip stripper =
// add whatever you want by name.
// executable's Main(string[] args) will be added automatically
stripper.EntryPoints.Add("MyNamespace.MyClass");
stripper.EntryPointBamls.Add("ui/mywindow.baml");

// walk the assembly opcodes to find all types, references and resources used
// all resources named "%usedType%.resources" will be counted as used
// walk the assembly opcodes to find all types and references used
stripper.ScanUsedClasses();

// walk the assembly types to find all that is not used
// walk the assembly types to build list of all types that aren't used
stripper.ScanUnusedClasses();

// remove all unused types
Expand All @@ -50,7 +52,10 @@ stripper.CleanupUnusedClasses();
// exclude necessary resources from cleanup
stripper.UnusedResourceExclusions.Add("MyNamespace.MyImage.png");

// remove all unused WinForms resources
// exclude necessary WPF resources from cleanup
stripper.UnusedWpfResourceExclusions.Add("res/myimage.png");

// remove all unused WinForms and WPF resources
stripper.CleanupUnusedResources();

// remove all unused references
Expand All @@ -60,39 +65,79 @@ stripper.CleanupUnusedReferences();
stripper.MakeInternalExclusions.Add("MyNamespace.MyClass");

// hide all other with internal
stripper.MakeNotPublic();
stripper.MakeInternal();

stripper.Save(outputPath);
// stripper.Save(outputStream);
```

### Commandline Tool

In reasons of convenience there is a commandline tool, built from improvised means. This makes the ILStrip to work as standalone or as a part of any build script.
In reasons of convenience there is a commandline tool, built from improvised means.
This makes the ILStrip to work as standalone or as a part of any build script.
Usage:

Syntax: BrokenEvent.ILStrip.CLI.exe /i:%inputFile /o:%outputFile [options]
Syntax:
BrokenEvent.ILStrip.CLI.exe input output [-s] [-e MyNamespace.MyClass] [-h] [-he MyNamespace.MyClass] [-u] [-re MyNamespace.MyResource] [-we resources/myresource.png]

Arguments:
input Input assembly filename to process.
output Output assembly filename to save processed assembly.
-s, -silent Suppresses logging. Optional.
-e User defined entry point classes list to start analysis. Multiple values. Optional.
-h, -hide Hide public API with internal access modifier. Optional.
-he Exclusions for -h option. Multiple values. Optional.
-u Removes all unknown resources. Optional.
-re Resource exclusions for -u option. Multiple values. Optional.
-we WPF Resource exclusions for -u option. Multiple values. Optional.

/?, /Help - Displays the help message
/classes, /c - Clean unused classes.
/entry - User defined entry points list to start analysis. Multiple values.
/exclude - Exclusions from hiding list. Multiple values.
/hide, /h - Hide public API with internal.
/input, /i - Input assembly filename to process.
/output, /o - Output assembly filename to save.
/refs, /r - Clean unused references.
/res, /rs - Clean unused WinForms resources.
/s, /silent - Suppress logging.

### Analysis/How it works
The *ILStrip* will parse all the methods of classes and find all the types that was used. Then parse them and so on. The starting points of the scanning are called *entry points*. If the assembly is executable, the main entry method is is used as entry point automatically.
The *ILStrip* will parse all the methods of classes and find all the types that was used. Then parse them and so on.
The starting points of the scanning are called *entry points*. If the assembly is executable, the main entry method is used as entry point automatically.

You may add another *entry points* for classes, that will be instantinated with *reflection* or somehow else. It is used for classes, that have no internal references, but you want them to remain in assembly.
You may add another *entry points* for classes, that will be instantinated with *reflection* or somehow else.
It is used for classes, that have no internal references, but you want them to remain in assembly.

After building this list (`stripper.ScanUsedClasses()`) anything that isn't listed as used is trash. `ScanUnusedClasses()` builds the complete list of it.

Parsing of XAML/BAML is also supported. Any class which is referenced in BAML will be counted as used even if is the only reference.
Including ResourceDictionaries will work same way. Loading ResourceDictionary from code can't be detected. You should add such BAMLs as entry points.

### WPF
The WPF `Application` doesn't use XAML for startup. The startup window is called from code with XAML resource name in string.
This couldn't be detected so in this case you should manually add window class (or window BAML) to entry points.

However, if the window is started from code manually (`new MyWindow().Show()` or something like this) it will be detected as usual type reference.

### Resources

#### Default

By default ILStrip will try to cleanup only the resources that are known as unused. By default the following resources will be removed:

* Any `%className%.resources` embedded resource for class that is surely known as unused. These are mostly WinForms forms and controls.
* Any `.baml` from WPF resource which isn't built for some class (like XAMLs for windows and controls) and isn't referenced by other used BAML.

All other resources will remain in result assembly.

#### Full Cleanup

You can enable `RemoveUnknownResources` option which will remove everything which isn't surely known as used. In this case the following resources will NOT be removed:

* Any `%className%.resources` embedded resource for class that is surely known as used. These are mostly WinForms forms and controls.
* Any embedded resource, which name is added to `UnusedResourceExclusions`.
* Any `.baml` from WPF resource which is used by another BAML or related with used class.
* Any WPF resource, which name was added to `UnusedWpfResourceExclusions`.

Any other resource will be removed. Be very careful when using this option.

Both cases are not related with .NET resource manager, which is generated by Visual Studio. This resource will remain as is in any case.

## Credits
Uses [Mono.Cecil](https://github.com/jbevain/cecil).
Uses [Mono.Cecil](https://github.com/jbevain/cecil) from Mono project.

Uses [BamlParser](https://github.com/timotei/bamlparser) from Confuser.

© 2017-2019 Broken Event. [brokenevent.com](https://brokenevent.com)

Expand Down

0 comments on commit 4d68d8a

Please sign in to comment.