tags:

views:

120

answers:

1

I like to do my development as a normal (non-Admin) user. Our VS2010 project build fails with "Failed to register output. Please try enabling Per-user Redirection or register the component from a command prompt with elevated permissions."

Since I'm not at liberty to change the project file, is there any way that I can add user-specific MSBuild targets or properties that disable this step on a specific machine, or for a specific user? I'd prefer not to hack on the core MSBuild files.

I don't want to change the project file because I might then accidentally check it back in. Nor do I want to hack on the MSBuild core files, because they might get overwritten by a service pack.

Given that the Visual C++ project files (and associated .targets and .props files) have about a million places to alter the build order and to import arbitrary files, I was hoping for something along those lines.

MSBuild imports/evaluates the project file as follows (I've only looked down the branches that interest me):

Foo.vcxproj
  Microsoft.Cpp.Default.props
  Microsoft.Cpp.props
  $(UserRootDir)\Microsoft.Cpp.$(Platform).user.props
  Microsoft.Cpp.targets
    Microsoft.Cpp.$(Platform).targets
      ImportBefore\*
      Microsoft.CppCommon.targets

The "RegisterOutput" target is defined in Microsoft.CppCommon.targets. I was hoping to replace this by putting a do-nothing "RegisterOutput" target in $(UserRootDir)\Microsoft.Cpp.$(Platform).user.props, which is %LOCALAPPDATA%\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props (UserRootDir is set in Microsoft.Cpp.Default.props if it's not already set).

Unfortunately, MSBuild uses the last-defined target, which means that mine gets overridden by the built-in one.

Alternatively, I could attempt to set the %(Link.RegisterOutput) metadata, but I'd have to do that on all Link items. Any idea how to do that, or even if it'll work?

madgnome suggested that I could do something in the .vcxproj.user file. Unfortunately, that gets included right at the beginning of the build process, which means that replacing the target won't work.

A: 

Final tested solution

RegisterOutput is called during link process defined by $(BuildLinkTargets) (Microsoft.CppBuild.targets) as follow :

<BuildLinkTargets Condition="'$(ConfigurationType)'!='Utility'">
  $(BuildLinkTargets);
  _Link;
  _ALink;
  _Manifest;
  RegisterOutput;
  _XdcMake;
  _BscMake;
</BuildLinkTargets>

If you dont want to execute RegisterOutput you just have to delete this step in the definition of BuildLinkTargets :

<PropertyGroup>
    <BuildLinkTargets Condition="'$(ConfigurationType)'!='Utility'">
      $(BuildLinkTargets);
      _Link;
      _ALink;
      _Manifest;
      _XdcMake;
      _BscMake;
    </BuildLinkTargets>
  • If you dont want to execute RegisterOutput for one project, you need to override it in the file : *PROJECT_NAME.vcxproj.user* (next to your project file, this file is user and project specific)
  • If you never want to execute RegisterOutput in all your project, you need to override it in the file : $(UserRootDir)\Microsoft.Cpp.$(Platform).user.props (this file is user specific)
madgnome
That requires changing the project file. I'm unwilling to do that, because I might then accidentally check my changes back in and break everybody else's build. I need a solution that's specific to my user on my machine.
Roger Lipscombe
Not if you put the property in the file *.vxcproj.user
madgnome
Surely <EmbedManifest> is overkill?
Roger Lipscombe
My mistake the file *.vxcproj.user is only used in debugging. You'll have to use the user.props file. I think you could live with the manifest as a standalone file.
madgnome
No, the *.vcxproj.user file was a good suggestion -- it does get included in all builds, and I've only got to tackle a few projects. It'd be better in the .user.props file, but I'd like to override the metadata, I guess.
Roger Lipscombe
Ok I finally nailed it. See my edited answer above.
madgnome