Merge branch 'feature/msbuild'
This commit is contained in:
Коммит
18cffad542
|
@ -89,7 +89,7 @@ namespace Confuser.Core.Project {
|
|||
|
||||
if (IsExternal) {
|
||||
XmlAttribute extAttr = xmlDoc.CreateAttribute("external");
|
||||
extAttr.Value = IsExternal.ToString();
|
||||
extAttr.Value = IsExternal ? "true" : "false";
|
||||
elem.Attributes.Append(extAttr);
|
||||
}
|
||||
if (SNKeyPath != null) {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using System.IO;
|
||||
using System.Xml;
|
||||
using Confuser.Core;
|
||||
using Confuser.Core.Project;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Confuser.MSBuild.Tasks {
|
||||
public sealed class ConfuseTask : Task {
|
||||
[Required]
|
||||
public ITaskItem Project { get; set; }
|
||||
|
||||
[Required, Output]
|
||||
public ITaskItem OutputAssembly { get; set; }
|
||||
|
||||
public override bool Execute() {
|
||||
var project = new ConfuserProject();
|
||||
var xmlDoc = new XmlDocument();
|
||||
xmlDoc.Load(Project.ItemSpec);
|
||||
project.Load(xmlDoc);
|
||||
project.OutputDirectory = Path.GetDirectoryName(OutputAssembly.ItemSpec);
|
||||
|
||||
var logger = new MSBuildLogger(Log);
|
||||
var parameters = new ConfuserParameters {
|
||||
Project = project,
|
||||
Logger = logger
|
||||
};
|
||||
|
||||
ConfuserEngine.Run(parameters).Wait();
|
||||
return !logger.HasError;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\ConfuserEx.Common.props" Condition="Exists('..\ConfuserEx.Common.props')" />
|
||||
|
||||
<PropertyGroup Label="Assembly Settings">
|
||||
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>..\ConfuserEx.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Nuget Package Settings">
|
||||
<PackageId>Confuser.MSBuild</PackageId>
|
||||
<PackageLicenseUrl>https://github.com/mkaring/ConfuserEx/blob/master/LICENSE.md</PackageLicenseUrl>
|
||||
<PackageProjectUrl>https://github.com/mkaring/ConfuserEx</PackageProjectUrl>
|
||||
<PackageTags>Obfuscation Confuser ConfuserEx</PackageTags>
|
||||
<DevelopmentDependency>true</DevelopmentDependency>
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);IncludeConfuserDependencyFiles</TargetsForTfmSpecificContentInPackage>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Nuget Dependencies">
|
||||
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.7.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Label="Project Dependencies">
|
||||
<ProjectReference Include="..\Confuser.Core\Confuser.Core.csproj" PrivateAssets="all" />
|
||||
<ProjectReference Include="..\Confuser.Protections\Confuser.Protections.csproj" PrivateAssets="all" />
|
||||
<ProjectReference Include="..\Confuser.Renamer\Confuser.Renamer.csproj" PrivateAssets="all" />
|
||||
<ProjectReference Include="..\Confuser.Runtime\Confuser.Runtime.csproj" Condition="'$(TargetFramework)' == 'net461'" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="build\*" PackagePath="build" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="build\Confuser.MSBuild.targets" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="IncludeConfuserDependencyFiles">
|
||||
<ItemGroup>
|
||||
<ConfuserNetFrameworkDependencies Include="$(BaseOutputPath)\$(Configuration)\net461\*.dll" />
|
||||
<ConfuserNetFrameworkDependencies Include="$(BaseOutputPath)\$(Configuration)\net461\*.pdb" />
|
||||
<ConfuserNetStandardDependencies Include="$(BaseOutputPath)\$(Configuration)\netstandard2.0\*.dll" />
|
||||
<ConfuserNetStandardDependencies Include="$(BaseOutputPath)\$(Configuration)\netstandard2.0\*.pdb" />
|
||||
</ItemGroup>
|
||||
<CreateItem Include="@(ConfuserNetFrameworkDependencies)" AdditionalMetadata="PackagePath=netframework">
|
||||
<Output TaskParameter="Include" ItemName="TfmSpecificPackageFile" />
|
||||
</CreateItem>
|
||||
<CreateItem Include="@(ConfuserNetStandardDependencies)" AdditionalMetadata="PackagePath=netstandard">
|
||||
<Output TaskParameter="Include" ItemName="TfmSpecificPackageFile" />
|
||||
</CreateItem>
|
||||
</Target>
|
||||
|
||||
<Import Project="..\ConfuserEx.Common.targets" Condition="Exists('..\ConfuserEx.Common.targets')" />
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Confuser.Core.Project;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Confuser.MSBuild.Tasks {
|
||||
public sealed class CreateProjectTask : Task {
|
||||
public ITaskItem SourceProject { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] References { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem AssemblyPath { get; set; }
|
||||
|
||||
public ITaskItem[] SatelliteAssemblyPaths { get; set; }
|
||||
|
||||
public ITaskItem KeyFilePath { get; set; }
|
||||
|
||||
[Required, Output]
|
||||
public ITaskItem ResultProject { get; set; }
|
||||
|
||||
public override bool Execute() {
|
||||
var project = new ConfuserProject();
|
||||
if (!string.IsNullOrWhiteSpace(SourceProject?.ItemSpec)) {
|
||||
var xmlDoc = new XmlDocument();
|
||||
xmlDoc.Load(SourceProject.ItemSpec);
|
||||
project.Load(xmlDoc);
|
||||
|
||||
// Probe Paths are not required, because all dependent assemblies are added as external modules.
|
||||
project.ProbePaths.Clear();
|
||||
}
|
||||
|
||||
project.BaseDirectory = Path.GetDirectoryName(AssemblyPath.ItemSpec);
|
||||
var mainModule = GetOrCreateProjectModule(project, AssemblyPath.ItemSpec);
|
||||
if (!string.IsNullOrWhiteSpace(KeyFilePath?.ItemSpec)) {
|
||||
mainModule.SNKeyPath = KeyFilePath.ItemSpec;
|
||||
}
|
||||
|
||||
if (SatelliteAssemblyPaths != null) {
|
||||
foreach (var satelliteAssembly in SatelliteAssemblyPaths) {
|
||||
if (!string.IsNullOrWhiteSpace(satelliteAssembly?.ItemSpec)) {
|
||||
var satelliteModule = GetOrCreateProjectModule(project, satelliteAssembly.ItemSpec);
|
||||
if (!string.IsNullOrWhiteSpace(KeyFilePath?.ItemSpec)) {
|
||||
satelliteModule.SNKeyPath = KeyFilePath.ItemSpec;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var probePath in References.Select(r => Path.GetDirectoryName(r.ItemSpec)).Distinct()) {
|
||||
project.ProbePaths.Add(probePath);
|
||||
}
|
||||
|
||||
project.Save().Save(ResultProject.ItemSpec);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static ProjectModule GetOrCreateProjectModule(ConfuserProject project, string assemblyPath, bool isExternal = false) {
|
||||
var assemblyFileName = Path.GetFileName(assemblyPath);
|
||||
var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
|
||||
foreach (var module in project) {
|
||||
if (string.Equals(module.Path, assemblyFileName) || string.Equals(module.Path, assemblyName)) {
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
if (assemblyPath.StartsWith(project.BaseDirectory)) {
|
||||
assemblyPath = assemblyPath.Substring(project.BaseDirectory.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
}
|
||||
|
||||
var result = new ProjectModule {
|
||||
Path = assemblyPath,
|
||||
IsExternal = isExternal
|
||||
};
|
||||
project.Add(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using ILogger = Confuser.Core.ILogger;
|
||||
|
||||
namespace Confuser.MSBuild.Tasks {
|
||||
internal sealed class MSBuildLogger : ILogger {
|
||||
private readonly TaskLoggingHelper loggingHelper;
|
||||
|
||||
internal bool HasError { get; private set; }
|
||||
|
||||
internal MSBuildLogger(TaskLoggingHelper loggingHelper) =>
|
||||
this.loggingHelper = loggingHelper ?? throw new ArgumentNullException(nameof(loggingHelper));
|
||||
|
||||
void ILogger.Debug(string msg) => loggingHelper.LogMessage(MessageImportance.Low, "[DEBUG] " + msg);
|
||||
|
||||
void ILogger.DebugFormat(string format, params object[] args) {
|
||||
loggingHelper.LogMessage(MessageImportance.Low, "[DEBUG] " + format, args);
|
||||
}
|
||||
|
||||
void ILogger.EndProgress() {}
|
||||
|
||||
void ILogger.Error(string msg) {
|
||||
loggingHelper.LogError(msg);
|
||||
HasError = true;
|
||||
}
|
||||
|
||||
void ILogger.ErrorException(string msg, Exception ex) {
|
||||
loggingHelper.LogError(msg);
|
||||
loggingHelper.LogErrorFromException(ex);
|
||||
HasError = true;
|
||||
}
|
||||
|
||||
void ILogger.ErrorFormat(string format, params object[] args) {
|
||||
loggingHelper.LogError(format, args);
|
||||
HasError = true;
|
||||
}
|
||||
|
||||
void ILogger.Finish(bool successful) {
|
||||
if (!successful) {
|
||||
HasError = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ILogger.Info(string msg) => loggingHelper.LogMessage(MessageImportance.Normal, msg);
|
||||
|
||||
void ILogger.InfoFormat(string format, params object[] args) =>
|
||||
loggingHelper.LogMessage(MessageImportance.Normal, format, args);
|
||||
|
||||
void ILogger.Progress(int progress, int overall) { }
|
||||
|
||||
void ILogger.Warn(string msg) => loggingHelper.LogWarning(msg);
|
||||
|
||||
void ILogger.WarnException(string msg, Exception ex) {
|
||||
loggingHelper.LogWarning(msg);
|
||||
loggingHelper.LogWarningFromException(ex);
|
||||
}
|
||||
|
||||
void ILogger.WarnFormat(string format, params object[] args) => loggingHelper.LogWarning(format, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project>
|
||||
<Choose>
|
||||
<When Condition="'$(MSBuildRuntimeType)' == 'Full'">
|
||||
<PropertyGroup>
|
||||
<ConfuserAssemblyPath>$(MSBuildThisFileDirectory)\..\netframework\</ConfuserAssemblyPath>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<PropertyGroup>
|
||||
<ConfuserAssemblyPath>$(MSBuildThisFileDirectory)\..\netstandard\</ConfuserAssemblyPath>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<UsingTask TaskName="Confuser.MSBuild.Tasks.CreateProjectTask"
|
||||
AssemblyFile="$(ConfuserAssemblyPath)Confuser.MSBuild.Tasks.dll" />
|
||||
<UsingTask TaskName="Confuser.MSBuild.Tasks.ConfuseTask"
|
||||
AssemblyFile="$(ConfuserAssemblyPath)Confuser.MSBuild.Tasks.dll" />
|
||||
</Project>
|
|
@ -0,0 +1,156 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ConfuserKeyFile Condition="'$(ConfuserKeyFile)' == ''">$(AssemblyOriginatorKeyFile)</ConfuserKeyFile>
|
||||
<ConfuserIntermediateOutputPath Condition="'$(ConfuserIntermediateOutputPath)' == ''">$(IntermediateOutputPath)confused\</ConfuserIntermediateOutputPath>
|
||||
<ConfuserReplaceOutput Condition="'$(ConfuserReplaceOutput)' == ''">false</ConfuserReplaceOutput>
|
||||
<ConfuserOutDir Condition="'$(ConfuserOutDir)' == ''">$(OutDir)confused\</ConfuserOutDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(ConfuserProject)' == ''">
|
||||
<ConfuserProject Condition="Exists('$(MSBuildProjectDirectory)\$(MSBuildProjectName).crproj')">$(MSBuildProjectDirectory)\$(MSBuildProjectName).crproj</ConfuserProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ConfuserExDependsOn>
|
||||
CreateConfuserProject;
|
||||
ConfuseAssembly;
|
||||
_ReplaceOutputWithConfusedAssemblies;
|
||||
_ReplaceDebugOutputWithConfusedAssemblies;
|
||||
CopyConfusedFilesToOutputDirectory;
|
||||
</ConfuserExDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<Target Name="ConfuserEx"
|
||||
DependsOnTargets="$(ConfuserExDependsOn)"
|
||||
BeforeTargets="PrepareForRun" />
|
||||
|
||||
<PropertyGroup>
|
||||
<CreateConfuserProjectDependsOn>
|
||||
ResolveReferences;
|
||||
ComputeIntermediateSatelliteAssemblies
|
||||
</CreateConfuserProjectDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="CreateConfuserProject"
|
||||
Condition="$(DesignTimeBuild) != true And $(Obfuscate) == true"
|
||||
DependsOnTargets="$(CreateConfuserProjectDependsOn)"
|
||||
Inputs="@(IntermediateAssembly->'%(FullPath)');$(ConfuserProject);@(IntermediateSatelliteAssembliesWithTargetPath)"
|
||||
Outputs="@(IntermediateAssembly->'$(IntermediateOutputPath)%(Filename).crproj')">
|
||||
<Confuser.MSBuild.Tasks.CreateProjectTask
|
||||
SourceProject="$(ConfuserProject)"
|
||||
References="@(ReferencePath)"
|
||||
AssemblyPath="@(IntermediateAssembly)"
|
||||
SatelliteAssemblyPaths="@(IntermediateSatelliteAssembliesWithTargetPath)"
|
||||
KeyFilePath="$(ConfuserKeyFile)"
|
||||
ResultProject="@(IntermediateAssembly->'$(IntermediateOutputPath)%(Filename).crproj')"/>
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<ConfuseAssemblyDependsOn>
|
||||
CreateConfuserProject
|
||||
</ConfuseAssemblyDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="ConfuseAssembly"
|
||||
Condition="Exists('@(IntermediateAssembly)') And $(DesignTimeBuild) != true And $(Obfuscate) == true"
|
||||
DependsOnTargets="$(ConfuseAssemblyDependsOn)"
|
||||
Inputs="@(IntermediateAssembly->'%(FullPath)');@(IntermediateAssembly->'$(IntermediateOutputPath)%(Filename).crproj')"
|
||||
Outputs="@(IntermediateAssembly->'$(ConfuserIntermediateOutputPath)%(Filename)%(Extension)');@(IntermediateSatelliteAssembliesWithTargetPath->'$(ConfuserIntermediateOutputPath)%(TargetPath)')">
|
||||
<Confuser.MSBuild.Tasks.ConfuseTask
|
||||
Project="@(IntermediateAssembly->'$(IntermediateOutputPath)%(Filename).crproj')"
|
||||
OutputAssembly="@(IntermediateAssembly->'$(ConfuserIntermediateOutputPath)%(Filename)%(Extension)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_ReplaceOutputWithConfusedAssemblies"
|
||||
Condition="$(DesignTimeBuild) != true And $(Obfuscate) == true and '$(ConfuserReplaceOutput)' == 'true'"
|
||||
DependsOnTargets="ConfuseAssembly">
|
||||
<CreateItem Include="@(IntermediateAssembly->'$(ConfuserIntermediateOutputPath)%(Filename)%(Extension)')">
|
||||
<Output TaskParameter="Include" ItemName="IntermediateConfusedAssembly" />
|
||||
</CreateItem>
|
||||
<ItemGroup>
|
||||
<IntermediateAssembly Remove="@(IntermediateAssembly)" />
|
||||
</ItemGroup>
|
||||
<CreateItem Include="@(IntermediateConfusedAssembly)">
|
||||
<Output TaskParameter="Include" ItemName="IntermediateAssembly" />
|
||||
</CreateItem>
|
||||
</Target>
|
||||
|
||||
<Target Name="_ReplaceDebugOutputWithConfusedAssemblies"
|
||||
Condition="$(DesignTimeBuild) != true And $(Obfuscate) == true and '$(ConfuserReplaceOutput)' == 'true' and '@(_DebugSymbolsIntermediatePath)' != ''"
|
||||
DependsOnTargets="ConfuseAssembly">
|
||||
<CreateItem Include="@(IntermediateAssembly->'$(ConfuserIntermediateOutputPath)%(Filename).pdb')">
|
||||
<Output TaskParameter="Include" ItemName="_ConfusedDebugSymbolsIntermediatePath" />
|
||||
</CreateItem>
|
||||
<ItemGroup>
|
||||
<_DebugSymbolsIntermediatePath Remove="@(_DebugSymbolsIntermediatePath)" />
|
||||
</ItemGroup>
|
||||
<CreateItem Include="@(_ConfusedDebugSymbolsIntermediatePath)">
|
||||
<Output TaskParameter="Include" ItemName="_DebugSymbolsIntermediatePath" />
|
||||
</CreateItem>
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyConfusedFilesToOutputDirectory"
|
||||
Condition="$(DesignTimeBuild) != true And $(Obfuscate) == true and '$(ConfuserReplaceOutput)' != 'true'">
|
||||
<PropertyGroup>
|
||||
<!-- By default we're not using Hard Links to copy to the output directory, and never when building in VS -->
|
||||
<CreateHardLinksForCopyFilesToOutputDirectoryIfPossible Condition="'$(BuildingInsideVisualStudio)' == 'true' or '$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)' == ''">false</CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>
|
||||
<CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible Condition="'$(BuildingInsideVisualStudio)' == 'true' or '$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)' == ''">false</CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CopyBuildOutputToOutputDirectory Condition="'$(CopyBuildOutputToOutputDirectory)'==''">true</CopyBuildOutputToOutputDirectory>
|
||||
<CopyOutputSymbolsToOutputDirectory Condition="'$(CopyOutputSymbolsToOutputDirectory)'==''">true</CopyOutputSymbolsToOutputDirectory>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Copy the confused build product (.dll or .exe). -->
|
||||
<Copy
|
||||
SourceFiles="@(IntermediateAssembly->'$(ConfuserIntermediateOutputPath)%(Filename)%(Extension)')"
|
||||
DestinationFolder="$(ConfuserOutDir)"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
Condition="'$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)' != 'true'">
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="ConfusedMainAssembly"/>
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
|
||||
</Copy>
|
||||
|
||||
<!-- Copy the debug information file (.pdb), if any -->
|
||||
<Copy
|
||||
SourceFiles="@(IntermediateAssembly->'$(ConfuserIntermediateOutputPath)%(Filename).pdb')"
|
||||
DestinationFolder="$(ConfuserOutDir)"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
Condition="'$(_DebugSymbolsProduced)'=='true' and '$(SkipCopyingSymbolsToOutputDirectory)' != 'true' and '$(CopyOutputSymbolsToOutputDirectory)'=='true'">
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
|
||||
</Copy>
|
||||
|
||||
<!-- Copy the satellite assemblies (.resources.dll), if any -->
|
||||
<Copy
|
||||
SourceFiles="@(IntermediateSatelliteAssembliesWithTargetPath->'$(ConfuserIntermediateOutputPath)%(TargetPath)')"
|
||||
DestinationFiles="@(IntermediateSatelliteAssembliesWithTargetPath->'$(ConfuserOutDir)%(TargetPath)')"
|
||||
SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
|
||||
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
|
||||
Retries="$(CopyRetryCount)"
|
||||
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
|
||||
UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)"
|
||||
Condition="'$(_DebugSymbolsProduced)'=='true' and '$(SkipCopyingSymbolsToOutputDirectory)' != 'true' and '$(CopyOutputSymbolsToOutputDirectory)'=='true'">
|
||||
|
||||
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
|
||||
|
||||
</Copy>
|
||||
</Target>
|
||||
</Project>
|
|
@ -31,7 +31,7 @@ namespace Confuser.Renamer.Analyzers {
|
|||
if (!match.Success)
|
||||
continue;
|
||||
string typeName = match.Groups[1].Value;
|
||||
TypeDef type = mainModule.FindReflectionThrow(typeName);
|
||||
TypeDef type = mainModule.FindReflection(typeName);
|
||||
if (type == null) {
|
||||
context.Logger.WarnFormat("Could not find resource type '{0}'.", typeName);
|
||||
continue;
|
||||
|
|
|
@ -98,6 +98,8 @@ namespace Confuser.Renamer.Analyzers {
|
|||
}
|
||||
|
||||
void AnalyzeCAArgument(ConfuserContext context, INameService service, CAArgument arg) {
|
||||
if (arg.Value == null) return; // null was passed to the custom attribute. We'll ignore that.
|
||||
|
||||
if (arg.Type.DefinitionAssembly.IsCorLib() && arg.Type.FullName == "System.Type") {
|
||||
var typeSig = (TypeSig)arg.Value;
|
||||
foreach (ITypeDefOrRef typeRef in typeSig.FindTypeRefs()) {
|
||||
|
|
|
@ -40,7 +40,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Confuser.UnitTest", "Tests\
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntiTamper", "Tests\AntiTamper\AntiTamper.csproj", "{6A2BA6F7-3399-4890-9453-2D5BE8EEBBA9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AntiTamper.Test", "Tests\AntiTamper.Test\AntiTamper.Test.csproj", "{3F5558BD-7B94-4CB0-A46C-A7252B5BCA17}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntiTamper.Test", "Tests\AntiTamper.Test\AntiTamper.Test.csproj", "{3F5558BD-7B94-4CB0-A46C-A7252B5BCA17}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Confuser.MSBuild.Tasks", "Confuser.MSBuild.Tasks\Confuser.MSBuild.Tasks.csproj", "{91B12706-DC6A-45DE-97F1-FAF0901FF6AF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -100,6 +102,10 @@ Global
|
|||
{3F5558BD-7B94-4CB0-A46C-A7252B5BCA17}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3F5558BD-7B94-4CB0-A46C-A7252B5BCA17}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3F5558BD-7B94-4CB0-A46C-A7252B5BCA17}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{91B12706-DC6A-45DE-97F1-FAF0901FF6AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{91B12706-DC6A-45DE-97F1-FAF0901FF6AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{91B12706-DC6A-45DE-97F1-FAF0901FF6AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{91B12706-DC6A-45DE-97F1-FAF0901FF6AF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -16,16 +17,14 @@ namespace CompressorWithResx.Test {
|
|||
this.outputHelper = outputHelper ?? throw new ArgumentNullException(nameof(outputHelper));
|
||||
|
||||
[Theory]
|
||||
[InlineData("false", "normal")]
|
||||
[InlineData("true", "normal")]
|
||||
[InlineData("false", "dynamic")]
|
||||
[InlineData("true", "dynamic")]
|
||||
[MemberData(nameof(CompressAndExecuteTestData))]
|
||||
[Trait("Category", "Packer")]
|
||||
[Trait("Packer", "compressor")]
|
||||
public async Task CompressAndExecuteTest(string compatKey, string deriverKey) {
|
||||
public async Task CompressAndExecuteTest(string compatKey, string deriverKey, string resourceProtectionMode) {
|
||||
var baseDir = Environment.CurrentDirectory;
|
||||
var outputDir = Path.Combine(baseDir, "testtmp");
|
||||
var inputFile = Path.Combine(baseDir, "CompressorWithResx.exe");
|
||||
var inputSatelliteFile = Path.Combine(baseDir, "de", "CompressorWithResx.resources.dll");
|
||||
var outputFile = Path.Combine(outputDir, "CompressorWithResx.exe");
|
||||
FileUtilities.ClearOutput(outputFile);
|
||||
var proj = new ConfuserProject {
|
||||
|
@ -36,7 +35,17 @@ namespace CompressorWithResx.Test {
|
|||
{ "key", deriverKey }
|
||||
}
|
||||
};
|
||||
|
||||
if (resourceProtectionMode != "none") {
|
||||
proj.Rules.Add(new Rule() {
|
||||
new SettingItem<Protection>("resources") {
|
||||
{ "mode", resourceProtectionMode }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
proj.Add(new ProjectModule() { Path = inputFile });
|
||||
proj.Add(new ProjectModule() { Path = inputSatelliteFile });
|
||||
|
||||
|
||||
var parameters = new ConfuserParameters {
|
||||
|
@ -56,7 +65,8 @@ namespace CompressorWithResx.Test {
|
|||
using (var process = Process.Start(info)) {
|
||||
var stdout = process.StandardOutput;
|
||||
Assert.Equal("START", await stdout.ReadLineAsync());
|
||||
Assert.Equal("Test", await stdout.ReadLineAsync());
|
||||
Assert.Equal("Test (fallback)", await stdout.ReadLineAsync());
|
||||
Assert.Equal("Test (deutsch)", await stdout.ReadLineAsync());
|
||||
Assert.Equal("END", await stdout.ReadLineAsync());
|
||||
Assert.Empty(await stdout.ReadToEndAsync());
|
||||
Assert.True(process.HasExited);
|
||||
|
@ -65,5 +75,12 @@ namespace CompressorWithResx.Test {
|
|||
|
||||
FileUtilities.ClearOutput(outputFile);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> CompressAndExecuteTestData() {
|
||||
foreach (var compressorCompatKey in new string[] { "true", "false" })
|
||||
foreach (var compressorDeriveKey in new string[] { "normal", "dynamic" })
|
||||
foreach (var resourceProtectionMode in new string[] { "none", "normal", "dynamic" })
|
||||
yield return new object[] { compressorCompatKey, compressorDeriveKey, resourceProtectionMode };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ namespace CompressorWithResx {
|
|||
public class Program {
|
||||
internal static int Main(string[] args) {
|
||||
Console.WriteLine("START");
|
||||
Properties.Resources.Culture = new System.Globalization.CultureInfo("en-US");
|
||||
Console.WriteLine(Properties.Resources.TestString);
|
||||
Properties.Resources.Culture = new System.Globalization.CultureInfo("de-DE");
|
||||
Console.WriteLine(Properties.Resources.TestString);
|
||||
Console.WriteLine("END");
|
||||
return 42;
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace CompressorWithResx.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sucht eine lokalisierte Zeichenfolge, die Test ähnelt.
|
||||
/// Sucht eine lokalisierte Zeichenfolge, die Test (fallback) ähnelt.
|
||||
/// </summary>
|
||||
internal static string TestString {
|
||||
get {
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="TestString" xml:space="preserve">
|
||||
<value>Test (deutsch)</value>
|
||||
</data>
|
||||
</root>
|
|
@ -118,6 +118,6 @@
|
|||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="TestString" xml:space="preserve">
|
||||
<value>Test</value>
|
||||
<value>Test (fallback)</value>
|
||||
</data>
|
||||
</root>
|
|
@ -24,3 +24,7 @@ build:
|
|||
artifacts:
|
||||
- path: Release/bin
|
||||
name: ConfuserEx
|
||||
type: zip
|
||||
|
||||
- path: Confuser.MSBuild.Tasks/bin/Release/*.nupkg
|
||||
name: ConfuserEx.MSBuild
|
||||
|
|
Загрузка…
Ссылка в новой задаче