开发者

How to disable MSBuild's <RegisterOutput> target on a per-user basis?

开发者 https://www.devze.com 2022-12-29 00:33 出处:网络
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 com

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 o开发者_如何学JAVAnly 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.


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)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号