Friday, October 26, 2012

Fix F# WinRT Application Verification Problem

When you use Visual Studio 2012 F# portable library, you can run into the application verification problem. Here is the solution for VS2012 installation.




(1)      Add the following code to your portable DLL

 [<assembly:System.Resources.NeutralResourcesLanguageAttribute("en-US")>]  
 do()  

(2)      Go to the project properties for your F# portable DLL and do the following:
a.         Click on Build and set “Configuration” to “Release”
b.         Enter “--staticlink:FSharp.Core” to the “Other flags”
c.         Click on “Build Events”
d.         Set “Run the post-build event” to “When the build updates the project output”
e.         Paste the following text into “Post-build event command line”

 if \"$(ConfigurationName)\"==\"Release\" (  
 "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\ildasm.exe" /linenum /nobar /out="$(TargetName).il" $(TargetFileName)  
 powershell "$lines = '}','} /*','} */'; $matchCount = 0; $clashCount = 0; filter GetOutput { if ($_ -eq ' } // end of method MatchFailureException::.ctor') { $lines[$matchCount++] } else { if ($_ -eq '  } // end of method Clash::.ctor') { $lines[$clashCount++] } else { $_ } } }; (Get-Content $(TargetName).il) | GetOutput | Set-Content $(TargetName).il"  
 "C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe" /dll /debug=opt /quiet $(TargetName).il  
 copy /y $(TargetName).dll ..\obj\Release\  
 )  

        Alternatively, just edit the .fsproj of your portable DLL project and add the following at the end of the first PropertyGroup:

 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">  
   <OtherFlags>--staticlink:FSharp.Core</OtherFlags>  
  </PropertyGroup>  
  <PropertyGroup>  
   <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>  
   <PostBuildEvent>if \"$(ConfigurationName)\"==\"Release\" (  
 "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\ildasm.exe" /linenum /nobar /out="$(TargetName).il" $(TargetFileName)  
 powershell "$lines = '}','} /*','} */'; $matchCount = 0; $clashCount = 0; filter GetOutput { if ($_ -eq ' } // end of method MatchFailureException::.ctor') { $lines[$matchCount++] } else { if ($_ -eq '  } // end of method Clash::.ctor') { $lines[$clashCount++] } else { $_ } } }; (Get-Content $(TargetName).il) | GetOutput | Set-Content $(TargetName).il"  
 "C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe" /dll /debug=opt /quiet $(TargetName).il  
 copy /y $(TargetName).* ..\..\obj\Release\  
 )  
   </PostBuildEvent>   
  </PropertyGroup>  

1 comment:

Don Syme said...

This problem is fixed in Visual Studio 2012 Update 1. Recompile your portable profile components after installing.

However, a related issue remains for any code that uses an F# "exception" declaration, e.g.

exception BadThing of string

This is due to a bug in the F# compiler (which was not updated in VS Update 1, though FSharp.Core.dll was updated). For example, the F# Power Pack code for FsLex/FsYacc uses exception declarations of this kind.

The simplest workaround is to replace these definitions by a class definition, e.g.

type BadThingException(message:string) =
inherit System.Exception(message)

And replace places that catch the exception
try ... with BadThing(msg) -> ...

should be replaced by

try ...
with :? BadThingException as e ->
let msg = e.Message
...

After making this change systematically you should be able to proceed.