VS Installer copy different files per installer compilation - c#

I have a VS installer copying several files.
I need to maintain 2 differnt installers 1 with specific files included and the other without.
I want to use the same installer project.
I thought maybe this can be done - getting the differnt result according to some define parameter
how can I do this?

Found a way to do so.
using the MSBuild conditional dependencies and then using the output of some project.
MS Build conditional referencing

I do believe you can do this by putting code into the Pre-build and Post-build events of the installer project.
Use a compiler directive for each of the builds and then you put DOS command line stuff into the pre/post build event command line box depending on what you need to do. Then you just perform 2 builds with 2 difference compiler directives.
It's actually pretty simple, a simple copy of a file would be like:
copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)lib\$(ProjectName).dll"
Obviously, you would probably have more stuff than this in there but you get the picture. They're basic DOS batch file commands.

Related

Copy file from one folder to root directory

I have 2 folders named CONFIG1 and CONFIG2 in a Xamarin android project.
Each have one one file(json files) in respective folder.
But there is a task during compiling which looks for those specific file(only one) in
root directory of project.
So for the solution I want to copy the file during project build in the root directory by editing the project file.
I have tried with Copytooutputdirectory and copytopublishdirectory,but none of them working..
Please help..
You could do a pre-build task. I can't speak to the reliability of the pre-build tasks in Xamarin projects. Back in the day, they weren't stable. Maybe now they are.
Here's a picture of the Build Tasks tab (of the project's properties) in Visual Studio 2017, with the "Edit Post Build" dialog open. Basically, the pre- and post-build steps are mechanically identical. They run programs in the command shell of your operating system. The "syntax" is just the batch language of the OS. In Windows, for example, you might run a bunch of xcopy commands to move things around.
There's a preprocessor that does variable replacement before running your script...those are what are shown in the "Macros" section...along with their current values. The example passes the value of the $(TargetPath) to the update_agent.bat, which is a batch file stored in the root of our solution. There are a lot of variables to choose from...as I've attempted to show in the dialog box.
There are downsides to pre- and post-build steps. They'll resolve differently on different machines...but if you refer to files outside the solution, they may not be on every developer's machine in the same place...and the step will quietly fail.
Also, they're not portable between operating systems. I'm not even sure if VS offers pre- and post-build steps on the Mac OS version of Visual Studio.
These downsides are why there are a number of directives supported by the .CSPROJ
So, while this is an answer, I doubt it's the answer unless somebody has a better suggestion. It might get you past your immediate needs, however.
Edit
MsBuild.exe is the program that's actually processing your .csproj...and you can put MsBuild directives directly in your project. These directives can use the same set of replaceable variables that are in that pre/post build dialog. Might be a better way to go at it. Potentially more portable.
<Target Name="CopyFiles">
<Copy
SourceFiles="#(MySourceFiles)"
DestinationFolder="c:\MyProject\Destination"
/>
</Target>
Here's the Copy task from the MsBuild reference.

Output MSIL in separate file

How to output the generated MSIL code in a separate file? I know there was an compiler option, because I used it (I think in VS2012) for a short time, but I cannot find this option anymore, I cannot even find this option in the compiler options list.
To my knowledge, the only way you can create an IL file of your assemblies is to add Post-build events that will execute when the build is successful.
In VS, you can do this by going to opening Project properties screen, and going to the Build Events tab.
From there, just set a Post-build event, similar to the one below. Please note, I had to add the reference path of the ildasm.exe application to my Windows PATH environment variable. If you have to do the same, this will require a log out and back in, for it to work.

How do I find executables when debugging?

I have a Visual Studio solution with a number of C# application projects.
Solution/
A/
B/
C/
Installer (WiX)/
Some of these executables need to be able to run others. For example, A needs to be able to run B and C. This is easy once the entire package is installed, since the executables will all get installed to the same location. However, I am unsure how to find B.exe from A.exe when I am running the programs from inside Visual Studio, i.e., when I am testing and debugging.
How do I get the correct path, no matter if I running from Visual Studio or after installing the program fully? I have some ideas, but I am a bit frustrated with execution, and I'm hoping it's easier than it currently seems. I am comfortable editing the *.csproj files manually if that's what it takes.
Possible solution 1
I could put the paths in the App.config files. However, there are problems:
The files would need to be different for debug and release versions. This doesn't look easy. An answer on Stack Overflow recommends XSLT, which is somewhat pathological in its complexity and I especially don't want to learn yet another language just to solve such a simple problem.
I would need to edit the file before it gets included in the installer, which is possible (reference) but requires yet more code.
Possible solution 2
I could put the necessary paths in plain text files that are created using post-build steps, but I don't know enough batch scripting to be comfortable with this.
Possible solution 3
Somehow copy B.exe into the output directory for A, so B.exe is always in the same path relative to A.exe. This would be annoying, since there are already post-build steps which copy a bunch of dependencies for B.exe, and the files would need to be copied again during A's build process.
Possible solution 4
Somehow adjust the build process so there is only one output directory shared between all projects in the solution.
Non-solutions
I'd like to keep the solution so that it works after checking out a fresh copy of the repository from version control, which means that environment variables or command-line parameters won't work.

Cheap way to wrap .exe for Custom Tool?

I have a custom script language and a compiler (an EXE written in C) that turns that language in to C# code. I'd like to hook up the script compiler as a Custom Tool on script files in the solution, and have it generate C# code behind.
I've seen articles and tutorials online, and they all have you generate COM interfaces and register your custom DLL with the registry and GAC, and I really don't want to deal with all that.
Is there a wrapper or hack or 3rd party plugin somewhere that would make this easier? Like if there was a way to run a batch script as the custom tool, and have the code behind file get generated from the stdout of that, I could pipe the file from my compiler to stdout.
First off, I know you said you don't want to register through the MSFT way, but I suggest you reconsider. Details are here: http://msdn.microsoft.com/en-us/library/vstudio/bb166527.aspx
Now that we got that out of the way, my suggestion to you:
Put your exe in a fixed location (best spot is probably right in the root of your solution or repository). Next, run your tool manually once, this way you have the .cs files or whatever you are generating so you can add them to your solution. That way the C# compiler knows they are there and you just have to hit the build button and it'll have the files to build.
Next, create a pre-build event (under project properties, build events tab) that calls your exe with the appropriate command line arguments to make it do its thing (generate your new cs files). I suggest you edit your exe to take multiple files at a time, to make your pre-build command more simple. (This is where placing your file in the sln or repo directory is helpful, because you can use VS macros to get an absolute path to both your exe and the files to read in.)
What happens now, is before msbuild gets called (but after you hit build) your script (or exe) will run to generate new output files. Since msbuild hasn't started yet you can change any solution files to your hearts content and the changes will be picked up by both msbuild and eventually (probably once the build is complete) VS.
Notes:
I have never been able to get a build event to work on the first try, it usually throws an error that will show up in the VS error/warnings window. I usually copy the whole error into notepad (or scite) and edit it down to the actual command line with arguments. I then open up a command shell and try to execute it. The errors here are usually more helpful and you can tweak until you get it right and copy the changes back in to VS.

In Visual Studio, can I make one file run another's custom tool? (in this case using Xsd2Code)

I am trying to work out if it is possible, when using a Custom Tool in Visual Studio, to have a change in the contents of one file, trigger the Custom Tool of another.
My scenario is this:
In a Visual Studio C# project, I have an "master.xsd" xml schema which includes several other other xsd files. I am using the Xsd2Code Visual Studio Custom Tool to generate a .cs from the schema. This works fine when the master.xsd itself changes, but I would like the custom tool to run on the file master.xsd when one of the other xsds changes.
Is there any way of one file triggering another's Custom Tool?
[EDIT - more detail on why I'm looking into using a custom tool for this]
At present we have a GenerateFiles.bat file that calls Xsd2Code from the command line to generate the code fiels from the schemas (as suggested by MattDavey below). This works, is just too slow.
The problem is that on every build Xsd2Code will, run but because lots of other projects depend on this project with the schemas, they will all recompile too even though probably nothing has changed. The practical upshot is that even a minor change to a unit test involves half the projects recompiling. This is why we've been looking at the custom tool approach to only generate the code files if the schema changes.
I use Xsd2Code a lot in this way, but my approach is to add a pre-build event which calls the Xsd2Code command line and regenerates the xml on each build..
My pre-build event looks like this:
$(ProjectDir)BuildTools\Xsd2Code.exe $(ProjectDir)Api\Schemas\MySchema.xsd MyProject.Api.Schemas $(ProjectDir)Api\Schemas\MySchema.cs /platform Net40 /collection Array /sc+ /ap+ /if- /xa+
In your case you could run this pre-build step only on the master xsd (which i'm guessing xsd:Imports the other schemas), or you could run the command on each of your schema files individually.
The advantage for this is that, if I change the XSD schema, I get very useful compile time errors :)
Hope that gives you some ideas!
EDIT
I spent some time thinking about the issue you highlighted regarding build time and modified the pre-build script like so:
$(ProjectDir)BuildTools\Xsd2Code.exe $(ProjectDir)Api\Schemas\MySchema.xsd MyProject.Api.Schemas $(ProjectDir)Api\Schemas\MySchema.cs.temp /platform Net40 /collection Array /sc+ /ap+ /if- /xa+
fc $(ProjectDir)Api\Schemas\MySchema.cs $(ProjectDir)Api\Schemas\MySchema.cs.temp
if errorlevel 1 copy $(ProjectDir)Api\Schemas\MySchema.cs.temp $(ProjectDir)Api\Schemas\MySchema.cs /Y
del $(ProjectDir)Api\Schemas\MySchema.cs.temp
So Xsd2Code is now generating the source code into a temporary file, which is only overwriting the existing .cs file if it is different. This should mean that if the .xsd hasn't changed at all, neither will the generated .cs :)
You're still taking the hit of running xsd2code, but you're not taking the hit of msbuild rebuilding an entire chain of projects if the generated source was the same..

Categories