As a C# developer, I recently decided to take a crack at writing some C++ programs, mainly because I found an interesting C++ API I wanted to play around with. I wrote a very simple program a few days ago, compiled it on the x64 target platform, ran it, and everything was just peachy.
However, yesterday I changed some of the code, tried to compile it, but then the linker started to complain:
LNK1158: cannot run 'cvtres.exe'
As I am quite new to developing C++ programs, I thought I must had made some beginner's mistake. However, after checking all configuration, searching google for several hours, and trying several 'fixes', I'm starting to think this problem might be caused by something more delegate, and the point is: I cannot seem to resolve the issue at all, so I was hoping to get some good feedback here.
First of all, let me list my configuration:
This last point seems to be crucial, since the VC++ Directory settings determine which compiler and linker are used. At this point, the cross-compiler residing in the $(VCInstallDir)bin\x86_amd64-directory is used. Furthermore, all other directories seem to point at x64 versions of all libraries and so on.
When you google this problem, you will find out that the linker used (link.exe) wants to execute cvtres.exe, which it cannot find. This problem seems to occur when cvtres.exe is neither in the same directory as the linker, nor in a directory that is resolved using the PATH-variable.
So I verified this and there is indeed no version of cvtres.exe in $(VCInstallDir)bin\x86_amd64 (though there are versions of it in the base-directory ($(VCInstallDir)bin) and in the 'pure' $(VCInstallDir)bin\amd64 directory), nor does the PATH-variable contain any listing of a directory that contains a version of cvtres.exe.
-- Attempt #01 - Fix the problem at hand --
As a result, you might conclude that the error is, in fact, a legal failure and I should fix this by either copying a version of cvtres.exe directly in the $(VCInstallDir)bin\x86_amd64 directory, or edit the PATH-variable as such that it points to usable version of it.
Unfortunately, none of this works.
When I copy cvtres.exe from $(VCInstallDir)bin or $(VCInstallDir)bin\amd64 to $(VCInstallDir)bin\x86_amd64 and compile, I either get the same message (now referring to the exact location: 'cannot run $(VCInstallDir)bin\x86_amd64\cvtres.exe', though it is there) or the linker exits with some unknown error-code (probably because the version of $(VCInstallDir)bin\amd64 is native x64 unlike the x86 cross-compiler which I have found out to be running in WoW64 mode).
The problem with attempting to edit the PATH-variable such that the linker can find a version cvtres.exe also fails because I don't know with path to refer to (it seems there are many more versions of cvtres.exe kept in various locations, also in the .NET 4.0 SDK directory for example).
-- Attempt #02 - Circumvent the problem by trying a different approach --
Another path that I have taken is to try to use the compiler and linker in the $(VCInstallDir)bin\amd64 instead of the cross-compiler. After all, I am running a 64-bit machine so I shouldn't need to use the cross-compiler, though Microsoft seems to choose this one by default, regardless of your local configuration/OS.
So I changed the VC++ Directory to point to this location and indeed the problem no longer occurs, but now I got a tracker-problem running the CL.exe instead:
TRK0002: [CL.exe] '@[TempFile].rsp': Invalid handle.
When I look for this temp-file I cannot find it, but I'm not sure whether it is immediately deleted after compilation 'completed' or it was never present at all. Unfortunately, googling this issue is a dead end also, and MS Visual Studio 2010 team even recognise this issue but have put it on 'Won't Fix'. In short, compiling natively 64-bit seems to be a known, general problem with VS2010, so I decided to go back to square one on this one, especially since other people having this problem always say 'well you can fix this problem by just using the cross-compiler instead of the native x64 compiler'.
OK, so now I find myself running out of options... And the crazy thing is that it all worked fine just a few days ago and I'm pretty sure I did not change or install anything regarding this project, nor updated Visual Studio or the .NET Framework somehow. I even checked the Windows Updated but can't find any related updates for the last few days.
The only thing I could do, really as a last resort, is to downgrade the whole thing to 32-bit and download the 32-bit version of the API, but I'd really want to avoid this one because it seems to me I should be able to compile and run 64-bit applications on my 64-bit laptop/OS.
So please, any suggestions?
Update: According to this instruction from MS, the PATH-variable for the linker has to point at the base-directory of the VC++ install. That is the $(VCInstallDir)bin I have been talking about. I have tried this, but does not solve the issue. I am wondering what is happening in the background when a VS Build is fired that I don't seem to know of...
@Hans Passant: Thnx for the tip! Process Monitor shows me that link.exe is trying to find cvtres.exe on one of following locations:
Needless to say, cvtres.exe exists in none of these directories. It's rather strange that only those locations are searched. I would at least expect that $(VCInstallDir)bin was searched, since this directory is explicitly listed in both the VC++ Directories and in the PATH-variable (which I editted manually for this purpose). I guess this comes down to findout out why this behaviour is as it is....
Update2: Just to put out some extra info, I decided to copy cvtres.exe from the $(VCInstallDir)bin to the $(VCInstallDir)bin\x86_amd64 directory, based on my findings using ProcMon, just to see what was happening then. First of all, as before, Visual Studio tells me the following:
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\x64\Microsoft.Cpp.x64.Targets(389,5): error MSB6006: "link.exe" exited with code -1073741515. (The line here just refers to a settings that checks which non-zero exit-codes are acceptable - the actual error-code was returned by link.exe.)
However, in the output Window of ProcMon I can see that cvtres.exe is found and is performing a large amount of work - to completion as it seems, but I am not quite sure about that. Anyway, the error still prevents me from executing the created executable, since it complains a certain referenced library was not found. This is probably due to the fact that the linker did not finish correctly, so in short, it does not resolve my issue here.
Update3: Another 'interesting' thing I tried was to just create a new, plain Win32 project with all MS defaults and I didn't even touch the code that is generated for me (a main function returning immediately), just to see at least a single program compile. Suprisingly, I now get the same error as above (link.exe exited with code -1073741515), so now I really start to think something's really wrong with my installation here.
So then I tried to de- and reinstall the VC++ parts of Visual Studio, but to no avail... At this point a full install of Visual Studio is no option since I'm also still in the middle of developing C# projects and I have tons of other add-ins installed that just take too much of my time at the moment to re-install and reconfigure. I might try this in the weekend if nothing has worked out until then.
Instead, I did some research on the error code and I think it has something to do with the fact that link.exe cannot find or access a dependency it requires. I already turned off my VirusScanner just to be safe (doesn't help), so now I'm downloading the latest Windows SDK (7.1) to see if that does anything. If that doesn't help, I'm guess it is either a terrible bug, or my installation is really screwed up somewhere and I might have to reinstall VS and all it's stuff...
Thanks for the suggestions anyway!
The C:\Windows\System32\NV
path could point to a problem that is discussed here and here.
It seems some NVIDIA drivers that can switch graphics modes (integrated/discrete) can corrupt the system path in certain situations (e.g. with Intel Wireless paths on the system path).
Disabling the NV Services service may solve your problem.