Max number of times a DLL can be registered/unregistered? - com

Is there a maximum number of times that a DLL can be registered and unregistered in a specific time period?
Here's what I mean and why: I have a Continuous Integration package that builds my VB6 applications and in order to build each of the 80 components of the solution, I:
retrieve each project's dependencies
in turn
register the dll (in NAnt
using < comregister unRegister="false" ... ... >)
build the project
publish the output .dll or .exe
somewhere safe
un-register the dll (in NAnt using
< comregister unRegister="true" ...
... >)
Now, this all works 100% of the time, IF I build each of the 80 projects manually; however, if I get my NAnt script to build all 80 projects in turn (in the correct order) then the build fails, giving me this error in CruiseControls' output...
[comregister] Unregistering 1 files
[comregister] c:\location\myBuild.include(301,4): Error while unregistering 'c:\\[project-location]\lib\myDependentDLLFile.dll' Unable to find an entry point named '**DllUnregisterServer**' in DLL 'c:\\[project-location]\lib\myDependentDLLFile.dll'.
(I don't know where 'DllUnregisterServer' comes from though!)
The same error then appears for every subsequent project that I build past the point of failure, which is around the 50-projects-built area. What I mean, is that the first 50 projects build fine, then the rest fail in-turn.
I have mitigated this by using the failonerror="false" attribute within the comregister call inside NAnt, but this then throws doubt in my mind as to whether this is ok or not...!
Ideally, I'd like to remove the failonerror attribute and report genuine errors back to CruiseControl's logging facilities. Any thoughts or suggestions?

No there's no maximum. Use Dumpbin.exe or Depends.exe to take a look inside that DLL and check that DllUnRegisterServer entry point is actually defined.

I dont think teher is any limit to the no of DLL register/unregister.

Related

How to get nunit console 3 to output failed and ignored tests (only) to text files?

I understand that nunit console 3 can write to TestResult.xml after running the tests, where the TestResult.xml is located inside the directory specified by --work parameter.
But from what I can tell, TestResult.xml contains too many (irrelevant) details, that I don't need to fix my unit tests errors. All I need is just the failed or ignored test cases, just like what is displayed in command line prompt when I am running nunit console in it.
How to configure the parameters for nunit console 3 so that it only gives me failed or ignored test cases?
Sorry, I'm a few months late (unfortunately I came across this problem only now). But as far as I searched, the only possibility is to use XSL transformation. There are some applications that can convert the XML report file, but... I tested a few, but unfortunately the output was not that was I need.
Therefore I created a simple NUnit3summary application that can transform the standard XML output file to text file. I was surprised that nobody until now made something like this (or at least did not publish it). It were only two hours of work (first working version) and a few more to finish it to stare ready for publishing.
It is only a simple application that was aimed for my needs. You can use filtration for now only with another application, e.g.:
NUnit3summary.exe TestResult.xml | grep Failed >FailedTests.txt
You can see a practical application here (this is also the project where the application was needed, because of too many errors in unit tests).

The specified procedure could not be found - how to identify?

I'm developing plugins for a program. Whenever I try to load my plugin in that program it crashes with an the specified procedure could not be foundbut nothing more.
Well to have an insight I tracked with Process Monitor (or ProcMon). I set the filter to just print messages for the process of my main program. However that application shows me including the libraries ends (after wandering through PATH) at the right file - i.e. Result: SUCCESS.
So my computer left me pretty clueless, yet refuses to work. Has anyone an idea how identify the missing procedure?
N.B.: Additionally I ran the DependencyWalker which gave me the usual error message because it's deprecated (dependency walker gives me errors on the system that runs correctly) - which could indicate that all dependencies are found.

TFS Continuous Deployment for Windows Service?

I have managed to do Continuous deployment for my Web project using TFS Msbuild.
I have goggled for few hours but couldn't find a relative link to achieve Continuous Deployment for windows service.
Possible to do CD for windows service using TFS Build Definitions? i.e for every check in below steps should be performed, I am using TFS2010 with Windows Server 2008 R2
1] Stop Service,
2] Copy respective Project folder from (Source) Build server to (Destination Server)'staging server1' or 'staging server2'
3] Start Services (willing to do this step manually)
Any blog,tutorial references to achieve this? My guess is need to use Power shell scripts but not sure.
Should be ok, you'll need to install an agent on the box you're deploying to. And you'll need to be able to exit the XAML templates (you'll probably want to copy your existing template that does your build and just add the stop/copy/start stuff onto the end of it).
After your CI build, you'll need to edit it (the XAML template) to start and stop the service you can use the "invoke process" activity (you'll probably want to do something like make it generic and pass in the service name as an argument - note you can change the display names etc in the Metadata argument so it appears meaningful in your build definition).
As far as copying stuff across goes, you can do this fairly easily by accessing properties like the drop location.
Should be fairly straight forward - once you get your head round modifying the templates!
Edit:
Sorry for not responding sooner, I'd have to revise my earlier comment, this isn't as straight forward as it seems unless you really know what you want, I have been thinking about this and like skinning cats, there are more than one ways to achieve this... I've rewritten this a few times so I hope the edit's make sense :)
Boils down to the following:
1) Pass into your template the build agent/machine you want to run this on (this can be done as a simple string, or as an AgentReservationSpec - up to you), since it's unlikely to be the machine that you run your actual CI build on. This is done in the Arguments section of the XAML, as noted before, if you want to edit the display name/description you can edit the Metadata Argument. This machine needs a TFS agent installed of course.
2) Run the task on the remote machine, this is done by adding the Agent Scope activity into your template, you will have to use the info from step 1 to get the ReservationSpec (so would be easier if you add the argument as an AgentReservationSpec or you'll need to resolve this in the template)
2.1) Run the stop/uninstall, this is done via dropping in a (two actually) Invoke Process activity, Invoke Process can take arguments and you need to point it to the executable you're executing, so you'll want to use this, one for the NET command (i.e. NET STOP ), and one for InstallUtil.exe.
2.2) Copy the files from your CI to the remote server, you can use the Copy Directory activity for this, it needs a couple of parameters, the main one is the source location, you should be able to drop in a GetBuildDetail activity, give it a name then reference .DropLocation to get this, destination is wherever you like you're installing to.
2.3) Install the new service as step 2.1, you need to use Invoke Process to install the service, then you can use another to start the service up.
I haven't covered everything, but I haven't set this up myself so I'm sure there are a few pitfalls or things I haven't though of. Off the top of my head this makes sense, but maybe someone that knows better can poke a few holes in it :)

Capture output of regsvr32 in an InvokeProcess TF Workflow Activity

I have a build process setup to build a managed solution using team build. This solution requires an unmanaged component be registered with the server before we build the solution as we interface with it via COM.
The activity (InvokeProcess) I use to register the ComObject looks something like this
regsvr32.exe /s ComObject.ocx
The activity (InvokeProcess) I use to unregister it looks something like this
regsvr32.exe /u /s ComObject.ocx
I have also added the WriteBuildMessage and WriteBuildError to both InvokeProcess activities using stdOutput and errOutput as the message for each action. I also make sure to set the build message importance to high.
It's my understanding that this should redirect the standard output and error output into these logging activities.
The registrion, build, and unregistrion works just fine as long as I do not set the /maxcpucount argument of MSBuild to anything greater than 1.
Once I set it to something greater than 1, our cleanup script at the end of the process fails with this error message when attempting to delete the file in question.
Access to the path '...\ComObject.ocx' is denied.'
I think what's happening is that the unregister activity is failing to unregister ComObject.ocx from the server because MSBuild isn't done with it when it's running across multiple cpu's. Then when I get down to try and delete it from the build server, it's still registered with the system and will fail with the access denied error.
So how do I get regsvr32 output to the stdOutput and errOutput so that the WriteBuildMessage and writeBuildError activities will properly display it in the build logs. If I call regsvr32 with a file that doesn't exist, I see nothing in the build log.
I hope this is makes sense.
Update
The solution to this problem came from a minor tweak of pantelif's solution. What I did was in the if block that throws an exception, I do a WriteBuildError using this as the message:
String.Format("ErrorMessage: {0}", New System.ComponentModel.Win32Exception( System.Runtime.InteropServices.Marshal.GetL‌​astWin32Error() ).ToString() )
This allows me to get the error from regsvr32.exe and write it to the build log.
As for your first question:
I believe it's possible to capture the output, by applying the technique presented by E.Hofman here.
More specifically, if you construct within your 'InvokeProcess' a sequence like presented (pic also from Ewald's post):
& then assign 'WriteBuildMessage' to stamp the 'ErrorMessage', you shall probably end up with getting the output you desire in the generated build log.

TFSBuild:How to trigger a build only when a particular file is checked in?

We have a particular file, say X.zip that is only modified by 1 or 2 people. Hence we don't want the build to trigger on every check-in, as the other files are mostly untouched.
I need to check for a condition prior to building, whether the checked-in item is "X.zip" or not.. if yes, then trigger a build, else don't. We use only CI builds.
Any idea on how to trigger the build only when this particular file is checked-in? Any other approaches would be greatly appreciated as i am a newbie in TFS...
Tara.
I don't know of any OOTB feature which can do this, what you would need to do is write your own custom MSBuild task which is executed prior to the build running (pre-build action).
The task will then need to use the TFS API to check the current check in for the file you want and if it's not found you'll have to set the task to failed.
This isn't really ideal as it'll indicate to Team Build a build failure, which, depending on whether you're using check in policies, may be unhelpful. It'd also be harder to at-a-glance work out which builds failed because of the task and which failed because of a real problem.
You can change the build to occur less frequently rather than every check in, which will reduce load on your build server.
Otherwise you may want to dig into Cruise Control .NET, it may support better conditional builds.
If you could move X.zip into it's own folder, then you could set up a CI build with a workspace that only looked at the folder containing X.zip.
You would then need to add an explicit call to tf get to download the rest of the code as Team Build only downloads what the workspace is looking at.
But this might be simpler than the custom task approach?