0

I've made a NuGet package that has managed and unmanaged code. The managed code is written in C# and supports AnyCPU while the unmanaged code is in C++ and has a 32-bit and 64-bit version. The managed code in this package is dependent on the unmanaged code. The structure of my package looks like this:

\build
     \x86
          unmanaged.dll
     \x64
          unmanaged.dll
     package.targets
\lib
     \net472
          managed.dll

Within my '.targets' file, I'm checking the $(Platform) variable to see if the user has selected x86, x64, or AnyCPU and copy the correct unmanaged dll to the output directory:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup Condition=" '$(Platform)' == 'x64' ">
    <Content Include="$(MSBuildThisFileDirectory)x64\unmanaged.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <Link>unmanaged.dll</Link>
    </Content>
  </ItemGroup>

  <ItemGroup Condition=" '$(Platform)' == 'x86' OR '$(Platform)' == 'AnyCPU' ">
    <Content Include="$(MSBuildThisFileDirectory)x86\unmanaged.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <Link>unmanaged.dll</Link>
    </Content>
  </ItemGroup>

</Project>

The expected behavior is when a user builds their program, the managed dll is copied over to the ouput directory with the correct umanaged dll according to the selected architecture type.

Everything works as intended when the user selects x86 or x64, but not when AnyCPU is chosen. This is because if the user has '32-bit preferred' off and the 32-bit unmanaged dll is copied to the output directory, an exception is raised saying that the format of the 32-bit unmanaged dll doesn't match the process' architecture, which is obvious. I want to modify my '.targets' file so it can recognize if '32-bit preferred' is toggled on or off and copy the correct unmanaged dll to the output directory when the program is being built. Is there a predefined Visual Studio variable that checks if '32-bit preferred' is toggled? If not, is there another way of checking the '32-bit preferred' option within the '.targets' file?

  • That doesn't help at all. Having "Prefer 32-bit" unchecked does not mean you don't need the 32-bit flavor. Happens when the code runs on a 32-bit OS or when the user references the package in a class library and that library is used in a 32-bit targeted app. The latter is a very common case. Consider to deploy them both and [select at runtime](https://stackoverflow.com/a/11936113/17034). – Hans Passant Dec 17 '19 at 18:57
  • You can try to remove `AnyCPU` platform from your solution and use only x86 and x64 – Pavel Anikhouski Dec 17 '19 at 18:57
  • @HansPassant what if both the unmanaged 32 bit and unmanaged 64 bit dll's have the same name? Then you wouldn't be able to deploy both and would only have to use one of them. – Neema Nejad Dec 17 '19 at 19:26
  • @PavelAnikhouski What would happen then when ```AnyCPU``` is selected and there's no condition checking for ```AnyCPU```? – Neema Nejad Dec 17 '19 at 19:27
  • @NeemaNejad If you remove it from solution properties, it can't be selected – Pavel Anikhouski Dec 17 '19 at 19:29
  • @PavelAnikhouski But the whole point is that I want the user to be able to just select ```AnyCPU``` and everything will be taken care of seamlessly without them having to explicitly select and configure ```x86``` or ```x64```. – Neema Nejad Dec 17 '19 at 19:34

1 Answers1

1

After some personal experimentation I found out the solution to my problem. I unloaded my project to see if there were any lines pertaining to '32-bit preferred' and I found a line saying <Prefer32Bit>false</Prefer32Bit>, meaning I could add this to my '.targets' file:

  <ItemGroup Condition=" '$(Platform)' == 'AnyCPU' AND '$(Prefer32Bit)' == 'false' ">
    <Content Include="$(MSBuildThisFileDirectory)x64\unmanaged.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <Link>unmanaged.dll</Link>
    </Content>
  </ItemGroup>

  <ItemGroup Condition=" '$(Platform)' == 'AnyCPU' AND '$(Prefer32Bit)' == 'true' ">
    <Content Include="$(MSBuildThisFileDirectory)x86\unmanaged.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <Link>unmanaged.dll</Link>
    </Content>
  </ItemGroup>

I tested this with my program to see if it would work and it was a success.