Select to view content in your preferred language

Single-file deployment failed

158
2
Jump to solution
Wednesday
Labels (1)
TaroShibata
Occasional Contributor

Hi,

I built a single-file executable in .NET with the following command for my application using ArcGIS Runtime.

dotnet publish -r win-x64

But I can’t run the generated .exe  with the following error message:

>Hello.exe
Unhandled exception. System.TypeInitializationException: The type initializer for 'Esri.ArcGISRuntime.Geometry.SpatialReferences' threw an exception.
 ---> System.InvalidOperationException: Invalid Wkid value (3857) creating a SpatialReference.
 ---> System.TypeInitializationException: The type initializer for 'RuntimeCoreNet.GeneratedWrappers.CoreSpatialReference' threw an exception.
 ---> System.DllNotFoundException: Dll was not found.
   at RuntimeCoreNet.GeneratedWrappers.CoreArcGISRuntimeEnvironment.<CoreRT_ArcGISRuntimeEnvironment_setInstallDirectory>g____PInvoke|69_0(Byte* __installPath_native, IntPtr* __outErrorHandle_native)
   at RuntimeCoreNet.GeneratedWrappers.CoreArcGISRuntimeEnvironment.<CoreRT_ArcGISRuntimeEnvironment_setInstallDirectory>g____PInvoke|69_0(Byte* __installPath_native, IntPtr* __outErrorHandle_native)
   at RuntimeCoreNet.GeneratedWrappers.CoreArcGISRuntimeEnvironment.CoreRT_ArcGISRuntimeEnvironment_setInstallDirectory(String installPath, IntPtr* outErrorHandle)
   at RuntimeCoreNet.GeneratedWrappers.CoreArcGISRuntimeEnvironment.SetInstallDirectory(String installPath)
   at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.InitNative()
   at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.InitializeRuntimeCore()
   at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.Initialize()
   at Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.OnBeforeFirstUseOfGeneratedWrapper()
   at RuntimeCoreNet.GeneratedWrappers.CoreSpatialReference..cctor()
   --- End of inner exception stack trace ---
   at RuntimeCoreNet.GeneratedWrappers.CoreSpatialReference..ctor(Int32 wkid)
   at Esri.ArcGISRuntime.Geometry.SpatialReference.CreateCoreCheckParams(Int32 wkid, Int32 vertId)
   --- End of inner exception stack trace ---
   at Esri.ArcGISRuntime.Geometry.SpatialReference.CreateCoreCheckParams(Int32 wkid, Int32 vertId)
   at Esri.ArcGISRuntime.Geometry.SpatialReference.GetFromCache(Int32 wkid, Int32 verticalWkid)
   at Esri.ArcGISRuntime.Geometry.SpatialReference.Create(Int32 wkid, Int32 verticalWkid)
   at Esri.ArcGISRuntime.Geometry.SpatialReferences..cctor()
   --- End of inner exception stack trace ---
   at Esri.ArcGISRuntime.Geometry.SpatialReferences.get_Wgs84()
   at Hello.Program.Main() in C:\Users\*******\source\repos\MyArcSample\Program.cs:line 14
   at Hello.Program.<Main>()



On the other hand, the executable produced by Build > Build {projectname} runs successfully.

 

So I’m wondering if I’m missing some configuration for the single-file build.
Do you have any ideas or hints on what could be causing this?

Thanks in advance.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <DefaultItemExcludes>$(DefaultItemExcludes);tests\**\*;tests/**\*</DefaultItemExcludes>
    <PublishSingleFile>true</PublishSingleFile>
    <SelfContained>true</SelfContained>
   <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
   <Platforms>AnyCPU;x64;x64</Platforms>

  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Esri.ArcGISRuntime" Version="200.8.0" />
  </ItemGroup>

  <!-- Copy shapefile components from the data folder to output and publish directories -->
  <ItemGroup>
    <None Include="data\**\*.shp" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
    <None Include="data\**\*.dbf" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
    <None Include="data\**\*.shx" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
    <None Include="data\**\*.prj" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
    <None Include="data\**\*.cpg" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
  </ItemGroup>

</Project>




 

 

0 Kudos
1 Solution

Accepted Solutions
imalcolm_esri
Esri Contributor
Hello,

 

It looks like you'll need to add <IncludeAllContentForSelfExtract>True</IncludeAllContentForSelfExtract> to the project file. You can replace IncludeNativeLibrariesForSelfExtract since IncludeAllContentForSelfExtract should cover the same functionality. More info here: https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=vs#native-librarie....

 

By default setting IncludeAllContentForSelfExtract will bundle the shapefile data specified in the ItemGroup and extract it to a temp folder at runtime. To return to the original behavior where you modify files in the same folder as the .exe file, a couple of changes are needed. First, you would replace the ItemGroup with a Target to copy the data manually like the following:
<Target Name="CopyShapefiles" AfterTargets="Build;Publish">
    <ItemGroup>
        <ShapefileComponents Include="data\**\*.shp;data\**\*.dbf;data\**\*.shx;data\**\*.prj;data\**\*.cpg" />
    </ItemGroup>
    <!-- Copy to output directory (for when building without publishing) -->
    <Copy SourceFiles="@(ShapefileComponents)"
          DestinationFolder="$(OutputPath)%(RelativeDir)"
          SkipUnchangedFiles="true" />
    <!-- Copy to publish directory (only applies to published builds) -->
    <Copy SourceFiles="@(ShapefileComponents)"
          DestinationFolder="$(PublishDir)%(RelativeDir)"
          SkipUnchangedFiles="true" />
</Target>

 

Second, you would need to change
var baseDir = AppContext.BaseDirectory;
to
var baseDir = Path.GetDirectoryName(System.Environment.ProcessPath);
in Program.cs as AppContext.BaseDirectory will point to the temp folder where the assemblies are extracted, not to the folder with the .exe itself.

View solution in original post

2 Replies
imalcolm_esri
Esri Contributor
Hello,

 

It looks like you'll need to add <IncludeAllContentForSelfExtract>True</IncludeAllContentForSelfExtract> to the project file. You can replace IncludeNativeLibrariesForSelfExtract since IncludeAllContentForSelfExtract should cover the same functionality. More info here: https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=vs#native-librarie....

 

By default setting IncludeAllContentForSelfExtract will bundle the shapefile data specified in the ItemGroup and extract it to a temp folder at runtime. To return to the original behavior where you modify files in the same folder as the .exe file, a couple of changes are needed. First, you would replace the ItemGroup with a Target to copy the data manually like the following:
<Target Name="CopyShapefiles" AfterTargets="Build;Publish">
    <ItemGroup>
        <ShapefileComponents Include="data\**\*.shp;data\**\*.dbf;data\**\*.shx;data\**\*.prj;data\**\*.cpg" />
    </ItemGroup>
    <!-- Copy to output directory (for when building without publishing) -->
    <Copy SourceFiles="@(ShapefileComponents)"
          DestinationFolder="$(OutputPath)%(RelativeDir)"
          SkipUnchangedFiles="true" />
    <!-- Copy to publish directory (only applies to published builds) -->
    <Copy SourceFiles="@(ShapefileComponents)"
          DestinationFolder="$(PublishDir)%(RelativeDir)"
          SkipUnchangedFiles="true" />
</Target>

 

Second, you would need to change
var baseDir = AppContext.BaseDirectory;
to
var baseDir = Path.GetDirectoryName(System.Environment.ProcessPath);
in Program.cs as AppContext.BaseDirectory will point to the temp folder where the assemblies are extracted, not to the folder with the .exe itself.
TaroShibata
Occasional Contributor

Thanks for your help — that solved my issue. @imalcolm_esri