I'm developing cross platform app using Xamarin.Forms, and I had some pain with the linker to build the release version. I use MVVM pattern, dependency injection for some services, value converters, behaviors, markup extensions... I've had to use the [Preserve(AllMembers = true)] attribute on many classes so that the linker wouldn't remove them.
Is it any way to preserve all shared project classes and members without using Preserve attribute in all "not used" files?
you can exclude entire assemblies from the iOS Linker
in the "additional mtouch arguments" under iOS project options
--linkskip=NameOfAssemblyToSkipWithoutFileExtension
in Android, you can use linkskip
<PropertyGroup>
<AndroidLinkSkip>Assembly1;Assembly2</AndroidLinkSkip>
</PropertyGroup>
Related
I need to protect the business logic on app and this is created with xamarin forms. I have searching information on forums and here about Babel and ConfuserEx but I don’t get it works.
Case Babel
I have installed demo SDK and I have updated the path on environment variables.
On Android Project I have added the following lines as I have seen on samples and book “Xamarin Mobile Development for Android Cookbook”
<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral, PublicKeyToken=138d17b5bd621ab7" />
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
<Babel InputFile="$(TargetPath)" OutputFile="$(TargetPath)"
VerboseLevel="5"
ObfuscateTypes="true"
ObfuscateEvents="true"
ObfuscateMethods="true"
ObfuscateProperties="true"
ObfuscateFields="true"
VirtualFunctions="true"
FlattenNamespaces="false"
UnicodeNormalization="false"
SuppressIldasm="true"
StringEncryption="xor"
ResourceEncryption="false"
ValueEncryption="false"
DynamicProxy="false"
ControlFlowObfuscation="goto=on"
ILIterations="5" />
</Target>
The compilation is good, but I see dll with ILSpy tool and I can see flow, methods, variables, etc…
Case ConfuserEx
I have installed the VS Extension of ConfuserEx and I have tried to actívate it on common Project and it is obfuscated but When I archive in order to generate the apk, it isn’t obfuscated.
I have tried to do on Android Project instead common Project, but it don’t work.
Could you give me some advice in order to obfuscate app? I want to do it with Android, iOS and UWP app.
Because by default, uwp, droid and ios is easy to do reversing engineering, no?
Because by default, uwp, droid and ios is easy to do reversing
engineering, no?
Assuming that this is the question, the answer is that you are mostly wrong.
AOT compiled assemblies are not easy to reverse engineer, and AOT is mandatory for UWP and iOS, while on Android partial AOT is enabled now by the default and full AOT can be enabled too on the VS Enterprise.
Speaking of that there is nothing that can't be reverse engineered and you can still add the obfuscation on the top of AOT compilation to make it even more tough, just there is no built-in solution (and as far as I know no free solution either) so it is yours to pick the one that you like, such recommendations are not allowed here.
I've been using Babel with my Xamarin.Android apps for the last 3 years. It works extremely well. If you are having problems contact Alberto at Babel. He provides really great support. Most problems are because of the fact that the Xamarin's build process can vary from release to release and therefore you Babel task can require modifications to accommodate those changes
I've tried to add a new reference to my .NET Core project.The strange thing is that I can access also the projects that are involved in my reference. For this example, i should be able to see the Repository project from service, but should not be able to access Entity Project.However , I can still access the entities object from Service.
How comes ?
References in SDK-based projects are fully transitive so - similar to many other package managers like npm or maven - you all the transitive references are available in the project to make sure the app compiles and runs cleanly, e.g. there are no unresolved references when the dependency is referenced and all assemblies are part of the build output and ready to run. (there may even be conflict resolution applied to conflicting version of assemblies resulting in the generation of binding redirects.)
In previous versions, you would need to install NuGet packages or add additional project references to other projects as well to not get build errors or type load exceptions.
Currently there is no perfect workaround if you want your project to do all the things needed to be able to run and resolve conflicts correctly but not pass transitive references to the compiler.
If you only need a dependency to build a project, but not to run it, you can mark a package or project reference as PrivateAssets="All" (add as attribute to the reference in the .csproj file).
If you want to enforce API usage - e.g. for layered APIs, consider writing a roslyn analyzer that will emit warnings if you reference APIs from places you don't want to. this may be suitable for large projects where tooling is needed to maintain the desired architecture.
I have a library, that target NETSTANDARD2_0 that used by full NET461 and NETCOREAPP2_0 clients.
I want to add to the library some Core2.0 specific code.
I am going to add APPNETCORE2_0 target and wrap the section with
#if NETCOREAPP2_0
#endif
It will create 2 separate target DLLs.
When I will refer my library from client Core2.0 application , will it refer NETCOREAPP2_0 DLL and ignore NETSTANDARD2_0 dll?
Is the order of selecting the version predefined and documented?
I will appreciate a link to the documentation.
Here is the official doc on creating these multi-targetted dlls. That explains how a different dll is generated for each target (such as net461 and netcoreapp1.0).
The official doc on how nuget resolves these to find the matching library covers how the right dll is selected:
When NuGet installs a package that has multiple assembly versions, it tries to match the framework name of the assembly with the target framework of the project.
If a match is not found, NuGet copies the assembly for the highest version that is less than or equal to the project's target framework, if available. If no compatible assembly is found, NuGet returns an appropriate error message.
Side note: you want NETCOREAPP2_0, not APPNETCORE2_0.
I am trying to create Team City build template which requires minimum customisation, and I want it to play nicely with legacy projects and projects developed with .NET Core/Standard and .NET CLI.
I am stuck with NuGet as there were some considerable changes in how things work.
Earlier we had to create nuspec file to pack project as a NuGet package. At least in that file we could define various package-related properties.
New csproj file format allows us to define all package properties inside itself. That's fine, but how then do we know which projects should be packaged and which should not?
So far our TeamCity's build step Pack NuGet just contained **.nuspec for Specification files: field. The very fact of nuspec file presence served like a flag pack & publish this project.
However, for dotnet pack we need to specify the project. There is no simple way to distinguish 'main' projects from 'auxiliary' ones on which mains depend. (Let us ignore that project-to-project references are currently not supported.)
We either could pack all projects specifying **.*proj (yet in that case we are to know which packages to publish) or we might specify projects explicitly in a build configuration, but I don't like this approach because you must edit build configuration each time new project is added to the solution.
I also considered the option Generate package on build and omit dot net pack step as package is created on build. The only thing left is publishing the packages with dotnet nuget push specifying **/%BuildConfiguration%/*.nupkg.
Unfortunately when starting build against solution without projects with enabled Generate package on build makes TC fail complaining that
Target files not found for pattern "**/Release/*.nupkg"
Hence, I either need another recipe for achieving the required result or an advice how to make TC consider empty result just as a NOP and mark build as successful.
Yet another option is to use nuspec even for new csproj...
Since TeamCity 2017.2 will be available option to associate build configuration with multiple templates. So you will be able to create different templates to create packages for old projects and new .NET CLI projects.
To specify paths for target .NET projects, which should be packaged, you could use build configuration parameters.
To set such parameters during the build you could send in the preceding build step service message. The value of this parameter could be set to the list of target project files which could be selected via script like that: https://stackoverflow.com/a/8153857/305875
I'm nearly done with my app. I'm using Xamarin.Forms (PCL project for the shared code). Is there any benefit of switching PCL into .Net Strandard? I have read some articles, but still not 100% sure whether are there any benefits of upgrading, e.g. security, performance or is't more like richer API mainly? Thanks for any thoughts.
There is no direct improvement in security or performance, but in time .NET Standard will replace PCLs. The PCL is not as cross-platform as Standard, so to make it truly cross-platform the switch to Standard is the smart thing to do.
Also, a lot of NuGet packages are already switching to support Standard, and you will not receive any upgrades for that code in your PCL library. So coming back to the security and performance part; if a bug is found in a NuGet package, you will not receive the update containing a fix because you're still on the 'older' PCL technology. This is a bit of a stretch, but if you want to be future-proof, the switch to .NET Standard is mandatory.
Right now we're in a bit of a pickle. You cannot reference a Standard from a PCL and vice versa (not 100% sure on all scenario's but I think you can't). So, right now you have to carefully check if all NuGets you are using, have a .NET Standard version already. If not, you're stuck on a PCL if you can't do it without the NuGet. The creator of the NuGet could supply a PCL and .NET Standard version in one NuGet, so then you can transition from one to the other. But see if that is true for all plugins you are using.
There is actually a good post on this by Adam Pedley here.
Actually, you can refer a PCL from .netstandard and vice versa, but it depends on netstandard version and PCL profile. Refer to this table to find out what is possible in your case.
To move from PCL to netstandard:
1. Replace *.csproj content with this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<PackageTargetFallback>$(PackageTargetFallback);portable45-net45+win81+wpa8</PackageTargetFallback>
<Copyright>Copyright © 2018</Copyright>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>
2. You can add PackageTargetFallback tag if you want add references to PCL libraries. Also you can edit the value you need. In the example above I use "portable45-net45+win81+wpa8" to add PCL(Profile111) in the netstandard1.1 library.
3. Use the netstandard version you need. Copy info from "AssemblyInfo.cs" to the project settings (Properties->Package) and remove it as you don't need it anymore.
4. Manually install back nuget packages from "packages.config" file and scan old *.csproj file for references to you projects. Add them as well. Then you can remove "packages.config" file as well.
I tried it on VS2017 15.7.5. I found that it's better to use netstandard1.1 and profile111 if you develop for Xamarin.Forms (Android + iOS). In this case, you can still use old .NETPortable nuget packages (even though they don't support netstandard yet).