Preserving ICommand during Linking - xamarin

In my Xamarin.Forms code I use ICommand several times for creating hyperlinks.
The code works fine during debugging, but the command gets removed during release by the linker.
I created an XML file in the root of my Android project with its Build Action set to LinkDescription, that has the following code:
<?xml version="1.0" encoding="utf-8" ?>
<linker>
<assembly fullname="System">
<type fullname="System.Windows.Input.ICommand"></type>
</assembly>
</linker>
I expected that would preserve the command, but no; the links again don't work during release. Am I doing something wrong?

I don't know why the XML solution did not work, but here is what worked in my case:
Using the [Preserve] attribute before each ICommand had the desired effect during Release!

You've got the wrong assembly. The easiest way to figure out the right assembly is to CTRL + Click the symbol ICommand in a Xamarin project, which will open a decompiler window with the assembly in a #region at the top of the file.
#region Assembly netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
// C:\Program Files\dotnet\sdk\NuGetFallbackFolder\netstandard.library\2.0.3\build\netstandard2.0\ref\netstandard.dll
#endregion
Now change the XML to:
<?xml version="1.0" encoding="utf-8" ?>
<linker>
<assembly fullname="netstandard">
<type fullname="System.Windows.Input.ICommand" />
</assembly>
</linker>

Related

How to read content of text file in Wix Toolset Bootstrapper

I am using the WiX toolset to build an installer, I want to read the version from a text file. The text file is located in mybootstrapper like below:
below is the code where i want to read the content of text file
<Bundle IconSourceFile='product.ico'
Name="Retail Grip"
Version="Version.txt" <!-- i know this is not correct -->
Manufacturer="Company Name"
UpgradeCode="PUT-GUID-HERE">
Oh, it is a WiX bundle - and that's "Wax"? I hear it is a WiX tool of sorts? I am not sure exactly how it works (screenshot down the page in that link). Maybe there are restrictions on the use of compiler variables when using it?
I wrote the below before I saw that Wax file and I thought you had a normal WiX source and not a bundle source. Either way, let me add what I wrote and see if it helps. Similarities.
Also: Neil Sleightholm's WiX Burn Template (towards top). Give that link a spin first please.
In a regular WiX file you could use a pre-processor variable: $(var.CurrentVersion) (compiler variable). Something like this:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define UpgradeCode="PUT-GUID-HERE"?>
<?define CurrentVersion="1.0.0.0"?>
<Product Id="*" Name="Sample" Language="1033" Version="$(var.CurrentVersion)"
Manufacturer="Someone" UpgradeCode="$(var.UpgradeCode)">
<...>
You can put the variables in its own "include file": Variables.wxi.
<Include>
<?define UpgradeCode="PUT-GUID-HERE"?>
<?define CurrentVersion="1.0.0.0"?>
</Include>
Larger sample here for this approach (do have a quick skim of this one).
And then include the file in your main WiX source:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include Variables.wxi ?>
<Product Id="*" Name="Sample" Language="1033" Version="$(var.CurrentVersion)"
Manufacturer="Someone" UpgradeCode="$(var.UpgradeCode)">
<...>
There are also localization variables: WiX (Windows Installer Xml), Create universal variables - link time variable resolution (light.exe), as opposed to the compile time resolution of pre-processor variables (candle.exe). Some context.
Some Relevant Links:
Localization Variables in use: Wix toolset license agreement multi-languages issue
How to make Win64 attribute as a variable in wixlib?
https://helgeklein.com/blog/2014/09/real-world-example-wix-msi-application-installer/
With WiX Include files, you can keep simple values separate from the bulk of the WiX markup. With WiX preprocessing, you can define named substitution values used in attributes or text nodes or conditional compilation, and then refer to them as $(var.name).
-- Version.wxi --
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?define Version="1.2.3" ?>
</Include>
-- Bundle.wxs --
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include "Version.wxi" ?>
<Bundle
Version="$(var.Version)"
…
It is sometimes convenient to generate include files in a source project in anticipation of them being used downstream, or generate them as the first steps of a WiX project.
I see you are using Visual Studio for your WiX Bootstrapper project. A Visual Studio project is a specialized MSBuild project (as are most types of Visual Studio projects). That means you can put general MSBuild things into the project file. You can open the .wixproj file as an XML file in an XML editor (such as Visual Studio).
MSBuild allows you define new tasks either from an external DLL or inline, using a .NET language. In this case, a few lines of C# will do fine to define the task. Then you would invoke it before the main build tasks. Like many build systems that use MSBuild, WiX ensures the target BeforeBuild is executed before it gets to work. So, you just have to define BeforeBuild.
The task is named CreateVersionWxi.
<UsingTask
TaskName="CreateVersionWxi"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
<ParameterGroup />
<Task>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Using Namespace="System.Xml.Linq" />
<Code Type="Fragment" Language="cs"><![CDATA[
var version = File.ReadAllText("version.txt");
var wxi =
new XDocument(
new XComment("*** GENERATED FILE. DO NOT EDIT ***"),
new XElement("Include",
new XProcessingInstruction("define", "Version='" + version + "'")));
wxi.Save("version.wxi");
]]></Code>
</Task>
</UsingTask>
<Target Name="BeforeBuild">
<CreateVersionWxi />
</Target>
Finally, if you add version.txt to your project with its Build Action, say, as Content, the project will be seen as needing to be rebuilt whenever version.txt changes. That will help if you have the WiX project open in Visual Studio while you are externally changing version.txt.
You don't need to add Version.wxi to your project but doing so increases its visibility to future maintainers.
Tip: Some Visual Studio users are more familiar with the Build Events on the project pages. To clue them in, you could enter this as a pre-build event command line: REM See the BeforeBuild target in the .wixproj file

No resource identifier found for attribute 'MvxBind' in package in Xamarin Android app

I'm using Xamarin Studio v5.10.1 and Xamarin Android v6.0.0.34 and MvvmCross v3.5.1.
I keep getting this error message when I build the solution:
No resource identifier found for attribute 'MvxBind' in package my.package
I've seen all the question in stack overflow regarding this error but nothing helped.
Here is what I tried:
Clean everything and rebuild
Used res-auto instead of my package name
Upgrade to the latest Mono Android
It seems that the file MvxBindingAttributes.xml is not copied to the Resources/Values folder. I assume it is supposed to be extract from Cirrious.MvvmCross.Binding.Droid.dll but somehow it doesn't.
I also tried creating the MvxBindingAttributes.xml file myself in the right place. It fixed the compilation error but a runtime error complaining about the same thing (resource id's not found).
Adding the MvxBindingAttributes.xml to the Resources/values folder in the solution worked for me.
https://github.com/MvvmCross/MvvmCross/blob/3.5/Cirrious/Cirrious.MvvmCross.Binding.Droid/Resources/values/MvxBindingAttributes.xml
I am also using xmlns:local="http://schemas.android.com/apk/res-auto" in the axml file
For me, my namespace in the XAML wasn't defined correctly...
I had:
xmlns:local="http://schemas.android.com/apk/res/AndroidApp1.Resource"
...
local:MvxBind
But the namespace of my app (in project properties) was AndroidApp1.AndroidApp1 (its a PoC :)).
So when I fixed that - it all worked:
xmlns:local="http://schemas.android.com/apk/res/AndroidApp1.AndroidApp1"
...
local:MvxBind
In my case, I mistyped the package name in the android manifest. Ensure that your xmlns:local attribute in the .axml file match the package name.
YOUR-PACKAGE-NAME must be the same here...
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/YOUR-PACKAGE-NAME"
android:layout_width="match_parent"
android:layout_height="match_parent">
and here
Hope it helps
OK. I just checked. It doesn't seem like the NuGet actually installs MvxBindingAttributes.xml into the Resources\values folder. So you have to create it yourself:
The contents need to be this: https://github.com/MvvmCross/MvvmCross/blob/3.5/Cirrious/Cirrious.MvvmCross.Binding.Droid/Resources/values/MvxBindingAttributes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MvxBinding">
<attr name="MvxBind" format="string"/>
<attr name="MvxLang" format="string"/>
</declare-styleable>
<declare-styleable name="MvxControl">
<attr name="MvxTemplate" format="string"/>
</declare-styleable>
<declare-styleable name="MvxListView">
<attr name="MvxItemTemplate" format="string"/>
<attr name="MvxDropDownItemTemplate" format="string"/>
</declare-styleable>
<declare-styleable name="MvxExpandableListView">
<attr name="MvxGroupItemTemplate" format="string"/>
</declare-styleable>
<item type="id" name="MvxBindingTagUnique"/>
<declare-styleable name="MvxImageView">
<attr name="MvxSource" format="string"/>
</declare-styleable>
</resources>
EDIT:
This information is not valid for MvvmCross 4.x where MvxBindingAttributes.xml is included in the MvvmCross.Binding package. This means, that it is no longer necessary to include this file yourself or through a NuGet into your project.
I know this question is real old but if you are having this error in Xamarin Studio version 6.1.5 and MvvmCross version 4.4.0 make sure you are creating a "Blank Android App" instead of a "Android App" This makes sure that no packages are included by default that will not play with with MvvmCross off the bat.
Try adding a reference from Manage NuGet Packages and from the search tap write MvvmCross.Bind and then install it.
I know it is old topic but I found another solution.
When you create new project remember to name core: name.Core and android app: name.Droid . It solved all my problems.

Enforcing files in a folder have build action = Embedded Resource with target files

The Visual Studio project has a folder containing sql scripts and all files in it must have the build action set to Embedded Resource. While adding new files, developers often forget to change the build action.
I want to create a target file that throws an error a compile time if any of the files in the folder do not have the correct build action.
I have seen something similar done before.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0"
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MakeSureSqlFilesAreSetToCopyAlways" BeforeTargets="PrepareForBuild">
<Error Condition="!('%(Content.CopyToOutputDirectory)' == 'Always')"
Text="This Content file is not configured to Copy Always: [%(Content.FullPath)]" />
</Target>
</Project>
This block of code checks if the files are set to copy always. How do I check build action?
Would appreciate some links to further reading on this topic as well.
Thanks in advance.
Assuming that script files are in a folder called Scripts, the following target file will raise an error if there's any file with build action set to Content and if their path contains the word Scripts.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0"
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MakeSureSqlFilesAreSetToEmbeddedAsResource" BeforeTargets="PrepareForBuild">
<Error Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Content.FullPath)', 'Scripts'))"
Text="This Content file is not configured as Embedded Resource: [%(Content.FullPath)]" />
</Target>
</Project>
If you're dealing with developers who forget to set their scripts as Embedded Resource, the above should be enough (though not comprehensive), mainly because Visual Studio sets the build action for new files to Content by default. If you want to make it bullet proof simply repeat the Error tag and replace Content with all possible build actions (except EmbeddedResource).

Renaming namespace in Java Bindings Library Project - Generator error

Following the directions at http://developer.xamarin.com/guides/android/advanced_topics/java_integration_overview/binding_a_java_library_(.jar)/api_metadata_reference/#Metadata.xml_Transform_File
<attr path="/api/package[#name='com.mycompany.myapi]" name="managedName">MyCompany.MyAPI</attr>
In this example, a Java library with a package
com.mycompany.myapi is mapped to the .NET namespace MyCompany.MyAPI.
I am trying to rename the namespace of a binding library project I created. The project successfully compiles before trying to do any transformations. Looking at the generated obj/debug/api.xml file the first few lines show
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<api>
<package name="android_serialport">
...
So to change the namespace from android_serialport to something like MyCompany.Ports.IO I am editing Transofrms/Metadata.xml to be
<metadata>
<attr path="/api/package[#name='android_serialport]" name="managedName">MyCompany.Ports.IO</attr>
</metadata>
However, with this added line I get an error that is rather cryptic:
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.targets(5,5): Error MSB6006: "generator.exe" exited with code -532462766. (MSB6006) (SerialPort)
The library I'm trying to create bindings to is was created in Android Studio to generate an aar. Without the transformation line added, everything compiles and I am able to reference it with no problem.
Anyone have experience with binding library transformations failing?
The error message is coming from the bindings generator. I was unable to find any docs on the error code, but it's being thrown due to a typo in the edited Transforms/Metadata.xml file:
path="/api/package[#name='android_serialport]"
should be
path="/api/package[#name='android_serialport']"
Notice the missing ' at the end of the #name. It's too bad the error message doesn't lead you to this.

Error: The element <ParameterGroup> beneath element <UsingTask> is unrecognized

I am receiving this error, when building the solution using the msbuild.
The element <ParameterGroup> beneath element <UsingTask> is
unrecognized.
The error is showing both in msbuild and in Visual Studio.
This is because one of your project is targeting .NET 3.5.
All of your projects should be targeted to .NET 4.0 at least.
If your .cs project does not allow to view or change the Target Framework, as it was in my situation: You will need to change it manually in .csproj.
Open the .csproj in notepad.
In this line
<Project ToolsVersion="3.5"...
change the ToolsVersion to at least 4.0.
Other possibility, is that you are using <UsingTask> inside a <Target> element.
You MUST declare it outside the <Target />.
Tested on 2017 and 2019.
The error is the following otherwise. (I would bet this is #Crono sees with Roslyn).
proj(2300,5): error MSB4067: L'élément "ParameterGroup" situé sous l'élément <UsingTask> n'est pas reconnu.
Just copy the config below and create a specflow.exe.config file
Put this config file next to your specflow.exe and you will be able to create the nunitexecutionreport report.
also can use this link https://github.com/techtalk/SpecFlow/wiki/Reporting
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0.30319" />
</startup>
</configuration>

Resources