1

MSBuild tells me that it cannot locate the reference included in the following task (this is an inline task):

<Task>
  <Reference Include="WindowsBase" />
  <Reference Include="$(SolutionDir)ImageTextWriter\bin\$(Configuration)\ImageTextWriter.dll" />
  ...
</Task>

I have confirmed that this file actually exists at the specified path. Yet MSBuild returns

System.IO.FileNotFoundException: Could not load file or assembly 'ImageTextWriter, Version=...

Am I doing something wrong?

Note: I'm not an MSBuild pro, but this post tells me that hard-coded paths should work.

dotNET
  • 33,414
  • 24
  • 162
  • 251
  • Try to print out the expanded version of path you are using. Chances are the path is different than you expect. If not, than there might be an issue with version or .net version of the referenced binary – Jan Nov 03 '17 at 11:04
  • If you get Undefined path from macro, [this](https://developercommunity.visualstudio.com/content/problem/3940/solutiondir-macro-at-pre-build-event-gives-undefin.html) post might be useful. – Renatas M. Nov 03 '17 at 11:08
  • @Jan: I printed that path and it seems to be okay. The DLL is using .NET 4.5, but that is what all other projects in the solution are using as well. – dotNET Nov 03 '17 at 11:26
  • The build rule is perhaps checked too soon, MSBuild tries to skip unnecessary work. Use the /verbose option to get a detailed trace of what it checks. Consider to get an answer that actually helps you by explaining why you think you need to write this yourself. – Hans Passant Nov 03 '17 at 11:52
  • @HansPassant: I read through MSBuild output. It looks like it successfully builds `ImageTextWriter` and copies it to `bin` directory. Thereupon, it starts processing my inline task but cannot locate `ImageTextWriter` assembly anymore. These two steps are listed next to each other in the output; there isn't anything in-between to suspect that the DLL might have been erased. – dotNET Nov 03 '17 at 12:08
  • *Consider to get an answer that actually helps you by explaining why you think you need to write this yourself.* I'm still trying to grasp this loaded sentence. :) – dotNET Nov 03 '17 at 12:09
  • @HansPassant: To confirm it further, I added a `` line immediately before calling my inline task with a **Condition** to ensure that the file exists. And the message actually comes up in the output, confirming that the DLL is available. It is getting stranger. – dotNET Nov 03 '17 at 12:11

2 Answers2

1

I wonder if strong assembly naming is the culprit. Try replacing

<Reference Include="$(SolutionDir)ImageTextWriter\bin\$(Configuration)\ImageTextWriter.dll" />

with

<Reference Include="$(SolutionDir)ImageTextWriter\bin\$(Configuration)\ImageTextWriter.dll">
    <SpecificVersion>False</SpecificVersion>
</Reference>

If that fails, revisit the possibility that the cleaning of ImageTextWriter.dll from bin/ earlier in the build is somehow responsible (even though your examination of the detailed log output earlier seemed to rule that out):

  1. Manually copy ImageTextWriter.dll to some arbitrary folder outside the project altogether.
  2. Temporarily change the Include path to the full, hard-coded path to that copy of the file.
  3. Click your heels three times...

EDIT

I did some testing and found:

  • SpecificVersion metadata is not allowed when the Reference element is in a Task. So much for my first idea above!
  • However, changing <Task> to <Task Evaluate="True"> is required for property expansion in the context where you are using $(SolutionDir) and $(Configuration).

    • Here is the construct with which I verified the behavior:
      
      <PropertyGroup>
          <pathfoo>C:\some\path</pathfoo>
      </PropertyGroup>
      <UsingTask [...]>
          <Task Evaluate="True">
              <Reference Include="$(pathfoo)\some.dll />
              [...]
          </Task>
      </UsingTask>
      
    • And here is the documentation that led me to try it (emphasis mine):

      UsingTaskBodyType Contains the inline task implementation. Content is opaque to MSBuild.

      UsingTaskBodyType_Evaluate ... Whether the body should have properties expanded before use. Defaults to false.

weir
  • 4,521
  • 2
  • 29
  • 42
  • I'll check this in the morning and get back to you. Thanks. – dotNET Nov 06 '17 at 17:35
  • @dotNET - Please check whether specifying `` (details above) does the trick. It was necessary in my own simplified test. – weir Nov 08 '17 at 21:30
0

You could try that one:

<Reference Include="ImageTextWriter">
  <HintPath>$(SolutionDir)ImageTextWriter\bin\$(Configuration)\ImageTextWriter.dll</HintPath>
</Reference>

But if this is the project that creates the ImageTextWriter.dll, I don't suppose that's possible.

PinBack
  • 2,499
  • 12
  • 16
  • For some reason, MSBuild doesn't like `HintPath` as a child of `Reference` node in a `.targets` file, though I can see `.vbproj` and `.csproj` file do use this method. – dotNET Nov 03 '17 at 13:04
  • You're right, you can't use a `HintPath` here. Are special characters in your `$(SolutionDir)`? As in your above linked post. – PinBack Nov 03 '17 at 13:57
  • No, I can't see any special chars, not even spaces. Names are longer than 8 chars, but that shouldn't be a problem. My gut feeling is that this has got something to do with assembly version. I manually copied the output DLL of the library into my main project as standard item and changed the above path to `$(ProjectDir)ImageTextWriter.dll`, but it still can't find it, saying that it can't locate ImageTextWriter Version 1.0.0.0. – dotNET Nov 03 '17 at 14:01
  • 1
    If you set the `Include` to a absolute Path e.g. `Include="C:\temp\ImageTextWriter\bin\Release\ImageTextWriter.dll"` there's still an error? – PinBack Nov 03 '17 at 14:24