Remove unnecessary files from release directory - c#

I use NSIS to create an installer for my project. Wishing to have as small a filesize as I can, I began looking into my project's dlls, included files and prerequesites and noticed the following are all different:
the minimal files required to run, as determined by educated guess + trial and error. I made sure the application works properly with this minmal set of files.
the files exported by the "Publish" fonction for click once deployment (excluding click once specific files)
the files in the release directory (excluding the pdb and vshost files)
It seems VS2015 generates an xml file for every dll. Some dlls I don't use and don't reference are copied as well.
My question is why is there so many unnecessary files and how can I configure VS2015 to not have them in /release?

If you set VS build log level to verbose you will see exactly what happends during build and why a file goes to release folder. Once you determine the reason, you may either change your project file to adjust predefined behavior or add post-build event to remove unwanted files produced by build process.
MSBuild file, located at "C:\Program Files (x86)\MSBuild\12.0\Bin\Microsoft.Common.targets" is very useful to dig into build process details as well.
However, if you indend to distribute the content of release folder to other machines I'd suggest you look at some installation software, like Wix, for example. Once you create a setup project which includes files you do want, there will be no need to fight for release folder content.

Related

Should each .Net Project in Solution have it´s own OutputFolder or not?

I have a solution with round about 50 Projects.
The default behavior of Visual Studio is to build each project into the project subfolders bin/debug and bin/release.
In my company there are guidelines that all projects should end up in a common output directory. The advantage should be that the files are not copied so often.
This is done defining the <OutputDirectory> in the .csproj file.
Checking the buildoutput showed me many deletes and copies of the same file. So I would expect that there are no advantages in copy count.
So are there any other benefits by sharing the output directory? Are there any problems that I not noticed yet?
What is the best practice handling this?
Thanks for your help :D
You can do this simply by using the MSBuild switch --output and specifying a folder for all the outputs when building a project/solution. All the dependent projects etc will be built and copied into one output folder.
I don't think it's particularly relevant "to reduce the number of files that are copied" - hard disks copy files all day, every day. Outputting into one folder can have a benefit when packaging for release; our Jenkins build server bundles all files into one folder before it puts them in a package (zip) file for Octopus deploy
You need to be careful htough, because it's possible for different projects to be dependent on different versions of the same DLL, and by mashing all the files together in one folder, DLLs of the same name (but different version) overwrite each other. You can then end up with a situation where your app doesn't load because it's trying for find XYZ DLL version 1.0 and some other project has a reference to version 1.1, and because that project built later, it's the 1.1 version of the DLL that ends up in the folder. You can then experience runtime errors indicating "The located assembly's manifest definition does not match the assembly reference" - it's saying "I was looking for 1.0, I found a DLL with the right name, but the version of the one I found was 1.1"
This can usually be solved with binding redirects, but it isn't 100% guaranteed that future versions of DLLs are backwards compatible with earlier versions. If you're arranging all your DLLs to copy into one folder youre creating a bit of a lottery for yourself as to whether things will break in production, when DLL versions go out of sync with what you expect
If your company operates a build and deploy process that uses locally copied versions of DLLs then it might be that they insist you do copy all DLLs to one folder to prove that the app will work in production - this is a much better reason (i.e. arrange a way for you to break the dev server so you can see and fix problems caused by DLL versions before putting to production and hitting the same) than "because we don't want the hard disk to get tired copying extra files"
If you insist to do that. You can
Right Click Your Project
Choose "Properties" => "Build Events" => "Post-build event command line"
Put xcopy "$(ProjectDir)\bing\debug{yourprojectdll}" "{path to shared folder}" /Y /I /R

wpf string files not found on release version but work in debug c#

I have finished a very basic application (wpf/c#). The solution is made of 3 projects:
The main project for the app
The Class Library Project to store app resources (images and txt files)
The Setup project which I use to create exe file for distribution to other
machines.
While the project works fine in debug mode when I deploy it using the Setup project and install on the computer I can access the image files from the Library Project (I can see there is a dll file for the library project in the application folder) but it fails to access the text files, complaining the path was not found. This is my very first time I completed the application and attempted to deploy it so am a bit at a loss why the setup does not provide correct references to the text files and yet it seems to work fine with image files which are located in the same library project.
Can someone point me in the right direction where to look at it to troubleshoot?
I have cleaned and rebuilt all projects in the solution. retested in debug mode (works fine). tried to search msdn and StackOverflow but I cannot find any guidance I could use or follow.
I would like to be able to display text from the text files in the released/installed application version the same way it works in debug mode. At the moment it fails to find the relevant txt files.
Finally, I have managed to crack it. Posting the answer for anyone having the same problem.
The issue here was not with the file path, even though I came up with a more clearer technique of building it, see my comments above. The problem was with the way Setup Project in VS2017 was creating a package. It is handling differently images and text files, even though both are in the same Library Project, essentially for text files I had to do the following to get it working:
Open File System in Setup Project
Create the 'Resources' Folder under 'Application Folder'
Set the 'Resource' folder 'AlwaysCopy' property to 'true'
In 'Resources' folder right-click and select Add> File...
Navigate to the folder with the files and select them all (make sure the files are setup as Resources or embedded resources)
Rebuild the Setup Project
.
So summarising I had to specifically tell Visual Studio to build the folder structure in the Application Folder during the install.
Now when I run the installer the text files are included in the package and created during standalone installation. Also included a screenshot below.

Windows installer (MSI) does not copy a config file

I installed an MSI buillder tool on my visual studio 2017 and started deploying my desktop application with generated MSIs. The istaller is able to copy vital files and adds registery keys but it does not copy some additional config files which are required for logger. According to this page, switching "Copy to Output Directory Property" to "Copy always" supposed to take care the issue however, it still does not copy the config file into output directory on client's computer.
Can somebody give an advice about how I can diagnose this problem ?
Edit:
I think I can explicitly add logs files into MSI with following method but I have two concerns on this. Would I add the file into MSI with its global or relative path ? Secondly will it be a good practice ?
Edit 2:
For the reference for developers who has the same issue, looks like the method stated above adds files with its relative path. I added screenshot of difference page at source control.
It is completely normal to add individual files to a VS setup project. Every tool that generates an MSI works this way. VS setups are probably the exception with their "project output" type of input choice, where you get little idea of the actual files that will be installed. So you get the best control of the MSI content by adding each file individually, including that config file. Also, some files really don't belong in the Application Folder (that defaults to Program Files) because they are data files that belong somewhere like the User's Application Data.
The path where the MSI build gets its files from is nothing to do with where that file is deployed on the target system. You tell the MSI build where files will be deployed on the target system by using the File System view on target machine, where you get a list of destination folders to add files to.
Also, the copy to output directory stuff is nothing to do with the build of the MSI file. As far as I know, its main reason is to allow you to have all dependencies at the output build location of the code so that the program will work correctly from that location, and it happens to give you the opportunity to get all the files going into a setup from the same place. It does not mean "copy this file somewhere in such a way that it is automatically included in the MSI build and the deployed on the target system".
Once you get the MSI working and installing the config file, you may run into Windows Installer file overwrite rules that prevent you from overwriting files that have been updated after they were installed.

Is obj/debug in a VisualStudio project, a temporary location?

In brief, I have a separate WCF VisualStudio Project, to compile the CLient and Contract dlls. Once I build the project using MS-BUILD(command line), i have a post-build nant task to copy over the Client and Contract dlls to another location.
Now it is easier for me to pick these dlls from obj/Debug folder(as they have only the CLient and Contract dlls and not their dependencies).
However I've heard that the obj/Debug folder is temporary.. and we need to rely on bin/Debug to get the dlls.
Is it necessary to pick it up from bin/debug and not obj/Debug and why ?
The role of obj\Debug is an undocumented implementation detail of MSBuild. It exists because MSBuild likes to conditionally copy files based on project settings. The exact rules are convoluted, to put it mildly, you could only gain insight by studying the .targets files in the framework directory. Which in themselves are highly dependent on the .NET version you target.
If you really want to know what makes it tick then do copy files from obj\Debug and see what hits the fan. Do beware that this may happen long after you created the project so there will forever be a cast of FUD when builds fail or produce the wrong file. If that doesn't sound very productive, it is not, then avoid breaking the warranty and copy from the project's output directory. bin\Debug and bin\Release by default. If that produces a problem then at least you can ask a question about it at SO.
Yes. You are supposed to pick up binaries from bin/Debug, or the variable OutputPath in MSBuild context more specifically,
http://msdn.microsoft.com/en-us/library/bb629394.aspx

When uploading a project to an open source repository, should one remove the bin and obj folders?

Just wondering what the standard practice is. Removing these folders before uploading makes the downloaded files easier to sort through and reduces the file count and size of the project (faster download). However, the downloader has to rebuild it to run it in his IDE of choice (in this case, VC#).
I will most likely have a separate download for the compiled binary so I imagine that removing the bin and obj folders would be desirable? Also, removing these folders remove all exe's and compiled files from the source code so they can be shared by services such as Gmail (Gmail does not allow emailing executables) without hassle.
yes, the obj and bin folders are generated by build process and are not needed by other developers to open the solution and rebuild the projects.
in general you should strip out also .suo files and other user specific files Visual Studio could create locally.
Yes, you should remove the binaries. As you said, you can offer separate binaries to download. If you have binaries in your version control repository, it also adds a bunch of unneeded file changes to your source control, making it harder sometimes to see what the real changes are.

Categories

Resources