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.
Related
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.
Debug (or Release) folder of my Desktop application when copied to another location does not run the exe. It issues no errors, but simply hangs the system for a second or two, but returns to normal straight away, as if nothing had been run.
Does Visual Studio 2015 create dependencies in upper hierarchy of Debug as well? My installer created using Wix was not running the intended exe and i thought it was Wix's problem. But then i tested it by copying the full Debug folder in a temporary subfolder and the app was not running even from there. It can only happen when it has dependencies present in places other than the Debug folder (because system resources (dlls) are accessed from absolute path of C: drive, so they would always be available.
Could there be something wrong in your manifest file or some other settings file? Some relative path pointing to a folder in your source hierarchy? Maybe it is just an image file or some sort of settings file that is missing? Or it might be something completely different.
A I wrote in your other question, one approach for hard-to-debug dependency scenarios is to just bite the bullet and run a thorough procmon.exe session (that is a direct hotlink to the live sysinternals tool share, clicking it will start the download instantly - just so you are aware).
You can see a quick description of how to use this tool in this question: Registering a CPP dll into COM after installation using Wix Msi installer. The key is to set an include filter which will show only events you need to see - basically for your own application.exe should suffice I believe.
Many find this procmon-stuff overkill, and don't want to deal with it - but trust me, it almost always reveals something unexpected (not always useful however).
As before this answer may also be worth a quick skim (on dependencies in general): After creating MSI Installer for WPF app in Visual Studio 2017, EXE does nothing. I would at least try the Dependencies.exe tool - even if it is a bit "beta-ish". You can download from here: https://github.com/lucasg/Dependencies/releases.
And certainly double-check the modules view in Visual Studio which I describe in the linked answer (Debug => Start Debugging, then go Debug => Windows => Modules). It should show whatever was loaded to run your project interactively.
I am having problems with a build server that I am trying to set up.
We use telerik, and have installed the libraries with the telerik control panel. The build process searches for the dll's all the wrong places.
Needless to say that the solutions builds perfectly on developer maschines.
The solution contains many projects, and not a single main project. I really do not want to have to change all the proj-files.
What I want is to add the telerik directory to AssemblySearchPaths, but using the msbuild parameters from the gui only got me to overwrite the AssemblySearchPath - with the result that the location of everything else but telerik files became unknown to build.
So I located a .targets file, which I read in the logfiles were utilized by build to set AssemblySearchPaths. And adding the telerik directory here did the trick (alas I still cannot get the build server to find the nuget dll's but that is another story).
However, I see that depending on selected CPU and perhaps other circumstances, the build uses another similar named .targets file from another location. Also, I find it less than optimal that such crutial customization is hidden away in a automatically installed file somewhere obscure.
So the question is: how to add more searchpaths to the ones already defined by the framework?
I am somewhat unfamiliar with ms build, but I did see an full fledged ms build file once which is why I knew it defines the build searh paths. However; alternatives which does not require that I change the projects in the solution will work for me.
Thanks!
Firstly, you need to be clear that: when you queue a build in VSO, the queued build is running on the Hosted Build Server. However, the software environment is different than developer machines, that is the reason why you can build successfully on developer machine but not on hosted build server.
If you would like, one easier way to resolve your issue is to set up the developer machine as the build server. You can register that developer machine with VSO, then all builds will run directly on the developer machine. Check this MSDN article for the details on how to set up build controller: https://msdn.microsoft.com/library/ee330987.aspx
If you don't like to set up the on-premise build server for VSO, you need to use Nuget restore function to resolve the assembly reference issue, because as far as I can tell configuring AssemblySearchPaths is not so convenient. Please check link for the details on how to have NuGet packages restored during the VSO (TFS) build process: http://docs.nuget.org/consume/package-restore/team-build
I'll give you 2 versions of my problem to describe it, first the short version.
When I try to build my application it does that perfectly and my app works but when I try to rebuild it, that fails and gives an error message saying that 2 files are missing (bin/debug/MusicPlayer.exe and bin/debug/MusicPlayer.pdb). When I then try to build normally, it fails to with the same error.
Now the longer version:
The way this happened was quite out of nowhere, I program on 2 different locations (both in Visual Studio 2010 sp1) but to always have the recent version in the right place I copy the entire solution folder to a usb stick, this folder I copy over again on the other PC and use it to continue were I left off, I've done this many times without problem. Yesterday however, I got an exception while testing the app. But instead of showing this in my code, it was complaining that it could not find the program.cs file (it was there, but apparently it had a different checksum (md5) and it asked me to use this one. After a while I found what part of my code caused the exception and fixed it. Since then I haven't got that error anymore. But when I later tried to rebuild instead of build, it gave me the error described in the short version. I have tried to fix it, but apparently I was not very successful.
Basically, what I think it does is delete the files in the debug folder that need rebuilding and then gives me the error of missing files (the files that it deleted) and thus failing to rebuild succesfully because these deleted files the normal build option won't work to.
(What I then do is re-copy them from my usb to make the normal build work).
Don't know if it's important, but I program in C# and I'm still learning.
Also when I copied it to my usb I believe I had no errors and the app was working fine (except the part I fixed later, which I could not test at that location). And when I build the entire solution it gives some warning ==> "Assembly 'bun/debug/MusicPlayer.exe' is incorrectly specified as file" and this for 5 files.
Does anyone know how to fix this rebuild problem and if necessary the warnings?
Thanks in advance
(and sorry for my bad English)
OK it seems like you might be confusing yourself with your directory structure here. If you want to add Content or Resources (Images, Text Files, etc.) you should place them in a folder within your project (not called bin or obj). All your build files will go here. Instead place the Content in another folder and Right Click -> Properties and Set the build action to "Content" or "Resource" and set the Copy to Output Directory (bin folder) to "Do not Copy" or "Copy if newer."
The project is failing because you have the built executable "MusicPlayer.exe" in your project. So Visual Studio is trying to build an executable file in adding to the project. Restructure your directories or remove "MusicPlayer.exe" ever time your build your project.
Do you have any anti-virus software running? They can go way too aggressive on removable drives. You are actually continuously deleting and creating a runnable program on usb stick by recompiling.
Just a guess tho...
Sounds to me like you have a pre- or post-build event with a hardcoded path in it. Fix that using variables and it should be ok.
I have a large solution containing many projects with one of them being a Setup project. There are also many current versions stored in separate branches. I have a build tool that used to work in .NET 2, but hasn't worked since we upgraded to .NET 4.
Internally, the new .NET 4 version of the build tool uses Microsoft.TeamFoundation.Client.RegisteredTfsConnections.GetProjectCollections() and versionControlServer.GetAllTeamProjects(false) to get a collection of TeamProjects from my TFS source control server.
I then display them visually in the UI and when a user clicks on a particular solution version, the application calls the following to get the latest for that solution version:
workspace.Get(new string[] { serverPath }, VersionSpec.Latest, RecursionType.Full,
GetOptions.GetAll);
The application used to build the solution files and this would include the Setup project. At this stage, the setup project would create an MSI that the application could be installed with. It is this last step that I am having problems with.
I need to be able to programmatically build the solution that the user selected using C# code. The working .NET 2 code for this was as follows:
Process process = new Process();
ProcessStartInfo processStartInfo = process.StartInfo;
processStartInfo.FileName = processName;
processStartInfo.Arguments = string.Format(" \"{0}\" /BUILD \"Release|Any CPU\"",
solutionPath);
processStartInfo.WorkingDirectory = processDirectory;
process.Start();
There is no error when this is run, but it no longer launches Visual Studio and builds the code. Clearly, this was a poor way to do it initially, but I can't find the 'correct' way using the TFS classes.
I also tried running MSBuild.exe directly (similar to the above example), and this does build the solution, but for some reason does not build the Setup project that produces the MSI. Note that I do NOT use any manually created build files.
Unfortunately, useful documentation for the Microsoft.TeamFoundation namespace is hard to find! I'm hoping that someone here has made use of these classes and can direct me to a solution to this problem.
If at all possible, I need to use .NET classes (eg. not Process.Start) as I really need to know when the build has finished as well. I can however set up a FileSystemWatcher object for this if this is asking too much.
msbuild skips the installer projects because it doesn't know how to build them. FinalBuilder shells out to devenv.exe to build these.
Calling `devenv /build "Release|Any CPU" /project "MyInstaller.vdproj" should run the build you need from the command line, without starting the VS GUI. Try it!
With all that said: We, too, use FinalBuilder, and VS Installer is deprecated, so you'll probably want to plan on replacing that.
It turns out that the problem was unfortunately completely unrelated. The .NET 2 code that was to be updated had hard coded 'Program Files' into the devenv.exe file path - however the new computers are 64bit and Visual Studio 2010 is installed into 'Program Files (x86)'!
So this means that the above code sample DOES work and WILL allow me to build the solutions from C#. It's not the object oriented way that I would have preferred to do it, but after all your comments, I'm just glad to have got it working at all.
Thanks for your time everyone.