How does one delete a registry value in MSBuild 4.0, without deleting the key?
I have tried the MSBuild Extension Pack, but the Registry class appears to be missing a method for deleting values.
Have you tried to use Exec and call command reg delete HKLM\Software\Test /v Testvalue
<Exec Command="echo Y|reg delete HKLM\Software\Test /v TestValue" />
Related
I have a .NET 6 project that includes some Exec nodes, and those commands are failing because (as in this discussion on the msbuild repo) the paths of the generated tmp<blah>.exec.cmd files are not whitelisted.
The suggested fix in there is
The location of this file is controlled by the environment variable
TEMP. Can you set that to a custom value before invoking MSBuild?
Which I'm sure would work - but I don't know how to do that. According to this question (which is for C++ not C#, but it's the best I can find) you can use EnvironmentVariables="<blah>" in that same node, but the files are still generated in %LOCALAPPDATA% despite my trying to set TEMP to something else. A failing example is below - what am I doing wrong?
<Target Name="ToolRestore" BeforeTargets="PreBuildEvent">
<Exec Command="dotnet tool restore" StandardOutputImportance="high" EnvironmentVariables="TEMP=C:\MSBuildTemp" />
</Target>
An answer should ideally be valid for building/debugging in Visual Studio and via dotnet build/test/publish. Even better would be a method of making the value of TEMP be variable per-user, but that's not necessary.
According to the code for the Exec task it does use the standard GetTempPath function, which means it really should react to user-level environment variables. However that function is documented like:
This method checks for the existence of environment variables in the
following order and uses the first path found:
The path specified by the TMP environment variable.
The path specified by the TEMP environment variable.
...
so the suggested fix you found is not entirely correct: you might need TMP not TEMP. And indeed on my machine I have TMP set and msbuild uses it for its temporary batch files which can be seen using a target which prints the path of the batch file Exec uses:
<Target Name="TempTest">
<Exec Command="echo %~dp0"/>
</Target>
Running on cmd.exe:
>set TMP=c:\temp
>msbuild temptest.proj /t:TempTest /v:m /nologo
c:\temp\
>set TMP=c:\Users
>msbuild temptest.proj /t:TempTest /v:m /nologo
temptest.proj(7,5): error MSB6003: The specified task executable "
cmd.exe" could not be run. Failed to create a temporary file. Temporary files folder is full or its path is incorrect.
Access to the path 'c:\Users\tmpb31f9faffaab49e9b3bd5479a6823550.exec.cmd' is denied.
I have read references that seem to suggest the ability to reference a bind or WiX variable at the command line (this one being the most obvious). This would give me the ability to add the Assembly Information to the name of the MSI that gets generated. For example,
light.exe ... -out Installer.!(bind.FileVersion.myExe).msi ...
light.exe ... -out Installer.!(wix.BlahInfo).msi ...
There is definitely some validation going on. If the WixVariable ID name is different between the WXS file and the reference in the light.exe command, I get an error:
light.exe : error LGHT0197 : The Windows Installer XML variable !(wix.BlahInfo1) is unknown
If I make sure they match, then the error disappears:
<WixVariable Id="BlahInfo" Value='!(bind.FileVersion.myExe)'/>
light.exe ... -out Installer.!(wix.BlahInfo).msi ...
However, no matter what I try, the resulting MSI file never does a run time variable replacement. Instead, it just adds the !(...) to the file name. As an example my last build produced a file with the following name:
Installer.!(wix.BlahInfo).msi
Is this something that can be done or have I misunderstood the documentation? Thanks.
Light doesn't support bind-time variable references on the command line.
So I reached the same conclusion as Bob. This wasn't acceptable since it introduced too much variability in builds so I solved it a different way. I knew that an executable run at the command line could reference a Windows environment variable at runtime. So all I needed to do was to set an environment variable and reference it and voila:
light.exe ... -out Installer.%BLAH_VERSION%.msi
To make this happen there was quite a bit that needed to get done. To start, my version number is coming from the Assembly Info of a Visual Studio project. The first thing I had to do was make it dynamic so that it created a new one for each build. Changing the last 2 numbers to a * did that:
[assembly: AssemblyVersion("6.4.*")]
The next thing to do was to externalize that number so it could be used elsewhere. Adding this stanza to the end of the csproj did that:
<Target Name="PostBuildMacros">
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="Targets" />
</GetAssemblyIdentity>
<ItemGroup>
<VersionNumber Include="#(Targets->'%(Version)')"/>
</ItemGroup>
</Target>
<PropertyGroup>
<PostBuildEventDependsOn>
$(PostBuildEventDependsOn);
PostBuildMacros;
</PostBuildEventDependsOn>
<PostBuildEvent>setx BLAH_VERSION #(VersionNumber)</PostBuildEvent>
</PropertyGroup>
Thanks to this stackoverflow post for help.
Of course to reference it, I would need to find a way to get an already opened command prompt to update its references to an environment variable. This proved to be the most difficult, but this stackoverflow post came to the rescue.
So now I have tied it all together using a windows batch script. Essentially, I build the EXE, test it, make sure it is good, run my batch script and I have an MSI file named after the assembly info version that was generated for me.
I am using WIX project to create an MSI file.
Following statements are added in WIXPROJ file to copy MSI file.
copy /y "!(TargetPath)" "$(MSIPath)\"
$(MSIPath) contains the path which is double byte characters.
Ex: F:\Temp\つも追加さ\
error MSB3073: The command "copy /y "E:\BuildMSI\bin\Debug\en-Us\xxx.msi" "F:\Temp\つも追加さ\"" exited with code 1.
Note: Same is working fine Japanese OS. This issue occurs in English OS.
Please help me how to resolve this issue.
Thanks in advance.
Regards,
Dileep
I have used the 'AfterBuild' command instead of 'PostBuildEvent'.
<Target Name="AfterBuild">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(MSIPath)" />
</Target>
Issue was solved using the above statements in Wixproject file.
I'm attempting to automate a roundtrip install and uninstall of a set of MSI files (generated by WiX) from a pack of sample programs. For some reason, a .MSI file that's perfectly happy to install on a double click generates:
This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.
when I invoke it with MSIEXEC in the following manner:
<ItemGroup>
<_SampleMsi Include="$(_ArtifactsPathAcceptanceSamples)\**\*.msi" />
</ItemGroup>
<Exec Command="$(WixDir)\smoke "%(_SampleMsi.Identity)""/>
<!--Guarantee precondition even if cleanup didn't work-->
<Exec Command="msiexec -passive -norestart -x "%(_SampleMsi.Identity)"" IgnoreExitCode="true" />
<Exec Command="msiexec -norestart -i "%(_SampleMsi.Identity)"" />
<!--Uninstall of every sample should also always work-->
<Exec Command="msiexec -passive -norestart -x "%(_SampleMsi.Identity)"" />
The same problem also happens when I try to uninstall based on the Product Id GUID:-
msiexec -passive -norestart -x FC7445BB-7E1D-4E36-A42A-CFA56263E453
What gives?
Just removed .\ prep-ending the filename and it worked.
Do not take the text of the message literally. About all you should be concluding is that misexec is treating some part of your command as a filename, and it didn't get to load and process the entirety of it to its satisfaction. Whether that's because the path was too long, permissions were refused, or any number of other conditions only limited by your imagination (most of the KB articles appear to pertain to Installer cache issues, which is generally the GUID-based syntax or patching/upgrading options)
You're missing the braces from the GUID, fool. I mean, you did know there are braces on the GUID even if msiexec /? doesn't tell you or show you, right?!
i.e. you need to replace FC7445BB-7E1D-4E36-A42A-CFA56263E453 with {FC7445BB-7E1D-4E36-A42A-CFA56263E453}
(I had stopped trusting/reading the outputs and was considering it a possibility that the GUID was resolving to a cached MSI which msiexec was unhappy with for the same reason that it appeared to be unhappy with the installation syntax which is what all the KB articles in this space tend to talk about.)
Your path contains relative jumps which, despite having a net length of <160 chars, have a gross length >160 chars so the underlying file APIs are choking. People like writing generic error messages that are misleading.
You can fix it by replacing Identity above with FullPath in each batching expression used.
Another way to remedy it is to use a WorkingDirectory with the Exec of msiexec
I have a .sln solution file that references a .csproj project file that has an after build task of something like:
<PropertyGroup>
<PostBuildEvent>
xcopy $(SolutionDir)\dir1\Somefle.xml $(ProjectDir) /Y /I
</PostBuildEvent>
</PropertyGroup>
The solution is built using msbuild with a task like the following:
<Target Name="CompileSolution">
<MSBuild Projects="#(SolutionToBuild)" Targets="Rebuild" Properties="Platform=Any CPU" />
</Target>
Now here's the strange part:
If I:
run the build script (say c:\MyWorkingCopy)
rename the working copy folder (say to c:\YourWorkingCopy)
run the build script again
On step 3, the xcopy will fail, because it will because it will be trying to copy the file from "c:\MyWorkingCopy" - which of course is not where the solution file now resides.
Why does msbuild use the old Solution directory? And is there some way to reset it?
(I am using .NET Framework 3.5)
It may be related to the sln.cache file that is created by msbuild when you build a sln file (it's a temporary proj file built from the sln one), if it is present or if the sln is not modified the sln.cache file may be used... I don't really know but it I think it could help.