WiX tool packaging, avoid ovewrite file on major upgrade - service

I have a problem with WiX when I try to generate an MSI (WiX v3.11).
My product is a windows service that must be installed, and during this installation process, I launch a form that collects information for connection to database. This information is stored in a .config file that is installed in the same application folder.
The problem is that if I do an update of the package, I must keep the configuration file, but if I uninstall the application, it should delete the configuration file.
The configuration file can be modified after or during installation.
<MajorUpgrade Schedule="afterInstallInitialize" />
<ComponentGroup Id="ConfigFiles" Directory="INSTALL_SERVICE">
<Component Id="ConfigFile" Guid="11FDDC05-F4D2-4418-82E8-0CB3B3784300" Win64="$(var.Win64)" NeverOverwrite="yes" >
<File Id="F.config" Name="service.config" DiskId="1" Vital="yes" KeyPath="yes" Source="..\Resources\service.config" />
<RemoveFile Id="CleanUpLogFile" On="uninstall" Name="service.config"/>
</Component>
</ComponentGroup>
With this I have managed to delete in the uninstall process and not be modified during the update, but the update process fails.
I have tried and read many solutions on the web but I do not get any of them working.

Related

Nuget Package Source is not prompting for credentials

I've added a NuGet Source. It needs credentials but when I'm installing a package using install-package packageName nothing happens.
I tried the same steps on other PC and it works.
I'm using Visual Studio 2017 Professional.
Could someone please help me with the issue?
My NuGet sources
This is riddiculous that it does not prompt for credentials.
To make it work I had to do the following:
Download nuget.exe from Nuget download site
Remove my old package source
Go to NuGet Package Manager for Solution->Settings
Delete your Package Source
Run Command Line
Go to nuget.exe
Add package source with plain password in the command
nuget.exe sources Add -Name "YourPackageName" -Source "YourPackageAddress" -Username YourUserName -password YourPassword -StorePasswordInClearText
Done... phew
If Visual Studio does not prompt for credentials but the logging Output shows that you did not authenticate correctly, then go to
Control Panel\User Accounts\Credential Manager
and click "Windows Credentials".
You can remove stored credentials for nuget/github there. If they become invalid - for example because you regenerated a token - Visual Studio does not prompt to overwrite the invalid credentials, but after removing the credentials and restarting Visual Studio you do get the prompt.
I've documented more troubleshooting related to the NuGet.Config in this issue:
https://github.com/verybadcat/CSharpMath/issues/168
Source for solving this specific problem:
https://support.microsoft.com/en-us/help/4026814/windows-accessing-credential-manager (I found this via: https://developercommunity.visualstudio.com/content/problem/98692/nuget-package-source-is-not-prompting-for-credenti.html)
After many attempts to set password, reset password or whatever the only thing that helped me was adding this section to the NuGet.Config (located on the .nuget folder for the main solution)
NuGet.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="false" />
</solution>
<packageSourceCredentials>
<MySourceName> <!-- Name of nuget package source -->
<add key="Username" value="..." />
<add key="ClearTextPassword" value="..." /> <!-- This is for normal password-->
<!--if encrypted use key="Password"-->
</MySourceName>
</packageSourceCredentials>
</configuration>
One important notice - for any change to this file to take effect I had to restart VS
Remove the source from the Nuget Package Manager and add it with a new name.
Credentials popup might be not coming because you have earlier entered some other credentials or some other credentials is stored against the NuGet Package. You can goto Credentials Manager in your PC and check for all NuGet Credentials.
If you found any, Please remove them from there. And, then try to restart Visual Studio and enter the package source and Url again. This time you will get the popup to add credentials for sure.

msbuild not able to write to files

I'm trying to create a build process using cruise control 1.8.5.0 with TFS 2010 running on a windows server 2008 R2 machine. The problem I'm running into is when MS Build is trying to write to files that ere just copied into the projects area it gets access denied. When I look at the files they are set to read only, the account that ccnet is running as is an admin on the box and everything is reading and writing locally. We have a similar environment setup on Windows Server 2003 and everything works just fine. We've verified that the account that is running the process is correct, I've set the owner of the projects folder to the same account that is running the process, we've disabled UAC. At this point I'm at a loss. Any additional information needed let me know.
Thanks
Robert
//When I look at the files they are set to read only, //
You can run the attrib to remove the read-only flag on the files.
quick example:
<Exec Command=“attrib -R $(SolutionRoot)\MyCoolFile.txt“ />
There is also a custom task:
<UsingTask AssemblyFile="$(MSBuildCommunityTasksLib)" TaskName="MSBuild.Community.Tasks.Attrib" />
I've not used it, but that would be enough to hunt it down.
I'd guess it would look like this:
<ItemGroup>
<Files Include="$(SolutionRoot)\MySubFolder\**\*.*/>
</ItemGroup>
<Attrib Files="%(Files.Identity)" ReadOnly="true"/>

Copy only newer files from one server to another server

I have a Build server and i would like to copy the newest deployment file from that location to another location on remote server using MSBuild but i am stuck on doing this as well as confused.
So in my build output directory i have a files such as this:
Installer - 2.5.1403.1201.msi
Installer - 2.5.1405.0701.msi
Now i want to copy the newest file Installer - 2.5.1405.0701.msi to remote server called ServerB.
I read that using PSExec shouldn't be used for copy files from build server to another server. Is there a reason why?
Currently i have the following code but i only got it to work locally on my machine:
<ItemGroup>
<File Include="C:\\LocalCopy\\Installer - 2.5.1403.1201.msi" />
</ItemGroup>
<PropertyGroup>
<DestinationFolder>C:\\Dump</DestinationFolder>
</PropertyGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="AfterBuild" Inputs="#(File)" Outputs="#(File -> '$(DestinationFolder)\% (RelativeDir)%(Filename)%(Extension)')">
<Copy SourceFiles="#(File)" DestinationFolder="$(DestinationFolder)" />
</Target>
Can someone provide me with advice how i could go about doing this?
Thanks & Regards,

How to modify the csdef defined in a cspkg

To deploy to different azure environments I modify the csdef as part of the compilation step to change the host headers. Doing so requires building the cspkg once for each environment instead of being able to reuse the cspkg and specify different configs for deployment.
I would like to instead modify the csdef file of a cspkg after it has been created, without recompiling. Is that possible, and if so how?
I've done something similar to what you're after to differentiate between test and live environments. First of all you need to create a new .csdef file that you want to use for your alternate settings. This needs to be the complete file as we're just going to swap it out with the original one. Now we need to add this to the cloud project. Right click on the cloud project and select unload project. Right click on it again and select Edit [Name of project]. There's a section that looks a bit like this:
<ItemGroup>
<ServiceConfiguration Include="ServiceConfiguration.Test.cscfg" />
<ServiceDefinition Include="ServiceDefinition.csdef" />
<ServiceConfiguration Include="ServiceConfiguration.cscfg" />
</ItemGroup>
Add a new ServiceDefinition item that points to your newly created file. Now find the following line:
<Import Project="$(CloudExtensionsDir)Microsoft.WindowsAzure.targets" />
Then add this code block, editing the TargeProfile check to be the build configuration you're wanting to use for your alternate and ensuring that it points to your new .csdef file
<Target Name="AfterResolveServiceModel">
<!-- This should be run after it has figured out which definition file to use
but before it's done anything with it. This is all a bit hard coded, but
basically it should remove everything from the SourceServiceDefinition
item and replace it with the one we want if this is a build for test-->
<ItemGroup>
<!-- This is an interesting way of saying remove everything that is in me from me-->
<SourceServiceDefinition Remove="#(SourceServiceDefinition)" />
<TargetServiceDefinition Remove="#(TargetServiceDefinition)" />
</ItemGroup>
<ItemGroup Condition="'$(TargetProfile)' == 'Test'">
<SourceServiceDefinition Include="ServiceDefinition.Test.csdef" />
</ItemGroup>
<ItemGroup Condition="'$(TargetProfile)' != 'Test'">
<SourceServiceDefinition Include="ServiceDefinition.csdef" />
</ItemGroup>
<ItemGroup>
<TargetServiceDefinition Include="#(SourceServiceDefinition->'%(RecursiveDirectory)%(Filename).build%(Extension)')" />
</ItemGroup>
<Message Text="Source Service Definition Changed To Be: #(SourceServiceDefinition)" />
</Target>
To go back to normal, right click on the project and select Reload Project. Now when you build your project, depending on which configuration you use, it will use different .csdef files. It's worth noting that the settings editor in is not aware of your second .csdef file so if you add any new settings through the GUI you will need to add them manually to this alternate version.
If you would want to just have a different CSDEF then you can do it easily by using CSPACK command prompt directly as below:
Open command windows and locate the folder where you have your CSDEF/CSCFG and CSX folder related to your Windows Azure Project
Create multiple CSDEF depend on your minor changes
Be sure to have Windows Azure SDK in path to launch CS* commands
USE CSPACK command and pass parameters to use different CSDEF and Output CSPKG file something similar to as below:
cspack <ProjectName>\ServiceDefinitionOne.csdef /out:ProjectNameSame.csx /out:ProjectOne.cspkg /_AddMoreParams
cspack <ProjectName>\ServiceDefinitionTwo.csdef /out:ProjectNameSame.csx /out:ProjectTwo.cspkg /_AddMoreParams
More about CSPACK: http://msdn.microsoft.com/en-us/library/windowsazure/gg432988.aspx
As far as I know, you can't easily modify the .cspkg after it is created. I guess you probably technically could as the .cspkg is a zip file that follows a certain structure.
The question I'd ask is why? If it is to modify settings like VM role size (since that's defined in the .csdef file), then I think you have a couple of alternative approaches:
Create a seperate Windows Azure deployment project (.csproj) for each variation. Yes, I realize this can be a pain, but it does allow the Visual Studio tooling to work well. The minor pain may be worth it to have the easier to use tool support.
Run a configuration file transformation as part of the build process. Similiar to a web.config transform.
Personally, I go with the different .csproj approach. Mostly because I'm not a config file transformation ninja . . . yet. ;) This was the path of least resistance and it worked pretty well so far.

.NET 2.0 app on Windows Server 2003 doesn’t load a .config file

I can’t made my .NET 2.0 applications (and services) to load their appname.exe.config files on Windows Server 2003 Standard Edition SP2,
I tried to create manifest like this but it didn’t worked
EDIT:
Appname.config is located in the same dir,
App works without any changes on Windows XP, once we move files or use setup to install it on 2003 it fails to load .config file.
The "working directory" of the executable IS the same as it's path! We didn’t change anything while moving it from XP to 2003
I’ve tried process monitor, it says for operations CreateFile and QueryOpen: name not fount, like this file would not exists, but I assure, it is!
I think it might be something wit manifest files under 200, according to this thred on MS Connect
but I don’t know how to solve the problem.
This might be the solution:
http://blogs.msdn.com/junfeng/archive/2006/08/09/692996.aspx
To workaround the bug, add an assemblyIdentity to the SxS manifest.
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
name="Foo"
type="win32"
/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Two things come to mind:
First, is the config file located in the same directory as the executable?
Second, is the "working directory" of the executable the same as it's path? If the working directory isn't correct, then it won't be able to locate the file.
One more thing to do would be to get a copy of sysinternals, specifically the process explorer tool to see what file (and path) it's trying to load.
What do you mean by cannot load? Any exception message .Net throws at you? Or it just dies silently?
Your app should load yourexe.exe.config, i.e., mainform.exe.config, where mainform.exe is your app name.