How to abort a commandline build.
I am trying to abort a commandline initiated build before it does any
work. I have a OnBuildBegin handler that does some checking to see
whether to actually build. None of my current approaches work reliably.- Invoking Build.Cancel in the handler. As far as I can tell, commands are not availablewhen running in commandline mode. Is that correct, or am I missing something?
- Using the HRESULT for the callback. As far as I can tell, that value is ignored.
- Hook into CommandEvents.BeforeExecute. I believe the same limitation will apply here as for invoking Build.Cancel. Commands seem to not be accessible (the build is not started via a command).
With that, I went off an tried a few things:
- To just abort builds in case of an error, I tried calling ExitProcess(0), which works great on 90% of all solutions. But hangs VS for some (it looks like managed code projects cause a hang/crash... I can make that happen by just calling ExitProcess(0) in that callback with a simple project).
- The next approach was to remove projects in the BeforeBuild callback, which didn't stop the build (VS apparently has compiled it's list of things to do by then).
- Then I closed the solution in the build callback, which just crashes VS I assume VS is not prepared to handle that).
- Call DTE.Quit() in the callback handler. As far as I can tell, that does nothing.
So here I am... any thoughts/suggestions/ideas/solutions?
Thanks,
Sven
Answers
- Thanks... I will try TerminateProcess. However, it seems that the behavior of TerminateProcess and ExitProcess is the same (except that one can be called on any Process), so I am not very hopeful.
Is there a way to hook into the solution loading and mark the solutions for not building? I noticed the put_IsDirty API for solutions, but I can not find a way to set that on all projects after the solution was loaded, but before VS computes it's build queue (also... I am not sure whether this API is actually doing what I think it does).
Alternatively, if the commandline build really only does a solution open, followed by a build invocation... is it feasible to just do that myself? What other things does devenev do? Invocation of Macros, etc.?
Thanks,
Sven All bug submissions should be done through the product feedback center at http://connect.microsoft.com/feedback/default.aspx?SiteID=210. This web site allows submission of zip files containing repro cases.
Craig
One possible solution suggested to me is to close the solution in the SolutionOpen event handler. That casuses the build to abort, but it also means that devenv returns an error code (still better than having it hang).
On a side note... the hanging problem with ExitProcess appears to be very reporducible for some machines, and not for others. I tried this on a fresh windows install with a clean VS install, and the problem does not occur. However, it happens all the time on other machines.
All Replies
1) When running on the command line, we do not create UI objects such as commands. We simply load the solution, start it building, then close. So firing a command will not be much help.
2) HRESULTs returned/exceptions thrown from an event handler are ignored by VS. We do not want to throw an error message in that case - any event code that wants to display an error would know how to better display that error than we would.
3) Correct, no commands so no command events.
1) My solution also would have been to call ExitProcess.
2 & 3) Removing objects in an event handler is not a good idea, as it can mess up our internal state. We try to block this in most situations, such as closing a document from within a DocumentClosed event.
4) DTE.Quit simply posts a command to ourselves. Since we do not accept any commands at that time, this command invocation is ignored.
Have you tried any of the other exit functions, such as TerminateProcess?
Craig
- Thanks... I will try TerminateProcess. However, it seems that the behavior of TerminateProcess and ExitProcess is the same (except that one can be called on any Process), so I am not very hopeful.
Is there a way to hook into the solution loading and mark the solutions for not building? I noticed the put_IsDirty API for solutions, but I can not find a way to set that on all projects after the solution was loaded, but before VS computes it's build queue (also... I am not sure whether this API is actually doing what I think it does).
Alternatively, if the commandline build really only does a solution open, followed by a build invocation... is it feasible to just do that myself? What other things does devenev do? Invocation of Macros, etc.?
Thanks,
Sven I think TerminateProcess is the same as ExitProcess, so I cautiously mention that as a possible fix.
When running from the command line, VS does very little other than load the project/solution files, and begin a build. So yes, you could do something like create an instance of VS using one of the CreateInstance APIs, and maintain a reference onto that object. When created through COM, we do create the UI and commands in the background, but we just never make the ShowWindow(...) call to display the UI to the user. Add-ins are run, so are macros, but the UI will be hidden. Unless the user calls code to show UI on startup or during one of the events, then this should not cause any problems for you. And if they do show UI, the proper way to handle this is check to see if the main window is visible.
Craig
- Haven't done the TerminateProcess yet. But I do have one question. I am now hooking into the Solution.Opened event, and am trying to mark the projects to not build when doing a commandline build. That would effectively skip the build (and would be much more graceful). I am trying to use put_IsDirty, but that appears to not work. Is there any way to do this?
Thanks,
Sven A few issues with this:
1) The solution opened event does not mean that the projects have been fully loaded and able to be programmed. There are some SCC scenarios where the event will fire, but the project will load async and the object model will not allow programming just yet.
2) put_IsDirty is a left over from VBx days. The object model in VS inherited some of the design from the VB line of dev tools. put_IsDirty and get_IsDirty was there to get and set the file saved to disk flag. However, when we moved to VS, we found that the put version did not make sense because it was not compatible with SCC. The philosophy at one time was that we would match the VB extensibility model's V-Table exactly, so we put the put property in there, but always return a bad hresult.
Craig
- Ok... so is there a way to disable the building of solutions/projects/configuration that I could do inside of an event to suppress the building of the solution?
Based upon the problems I have experienced using ExitProcess, I am now pursuing a different approach (and I hope you can help with that :-). Basically I figured that if I could just make devenv ignore the solution/projects for building I get the same effect as exit would give me, just that devenv can gracefully exit.
I tried setting ShouldBuild on the Context. Performing that change works fine when I do it on a non commandline build (with the interface up). The projects are all disabled in the context. However, in the commandline case, the change has no effect.
Thanks,
Sven - Tried TerminateProcess without any better luck.
- I narrowed the issue down to the existence of a Visual Studio Addin Setup project in the solution (vdproj). If the solution contains that project type, and the OnBuildBegin event calls ExitProcess, devenv will hang. The caveat is that I can see that on two of my machines every time, and on a third one never, so there appears to be some relation to the environment.
I can provide a zip file with the test case, but I don't see any way to do that here.
So I see three routes here:
1) Figure out why it hangs (I can't really do that, as this is all inside of devenv... if someone gives me the sources/symbols I am happy to try though :-).
2) Find another way to skip over the build step that does not involve a forced exit.
3) Run an external process that terminates devenv forcefully when the exit stalls.
Any help would be appreciated.
Thanks,
Sven All bug submissions should be done through the product feedback center at http://connect.microsoft.com/feedback/default.aspx?SiteID=210. This web site allows submission of zip files containing repro cases.
Craig
- Ok... I filed a bug report on the feedback forum.
One possible solution suggested to me is to close the solution in the SolutionOpen event handler. That casuses the build to abort, but it also means that devenv returns an error code (still better than having it hang).
On a side note... the hanging problem with ExitProcess appears to be very reporducible for some machines, and not for others. I tried this on a fresh windows install with a clean VS install, and the problem does not occur. However, it happens all the time on other machines.


