Automatically deploy referenced assembly as "Resource" in VS2005/Biztalk 2006 - visual-studio-2005

I have a two-project solution - one project contains my schemas and BizTalk orchestration, and the other contains a DLL that is referenced from my orchestration and does that actual work (it's shared code, so there's no chance I can just incorporate it into the BizTalk assembly). The second assembly is added as a reference from the BizTalk one, and I can reference the methods in #2 from the orchestration without any trouble.
However, when I deploy from VS -> BizTalk, it doesn't take my resource assembly with it - it just deploys the BizTalk assembly. If I attempt to trigger my orchestration, I'll get an error that the referenced assembly couldn't be loaded, but once I add it to the GAC and the "Resources" list for my BizTalk app, things run perfectly.
How can I flag this assembly as something that has to be deployed with my BizTalk assembly? Am I just missing a setting on the reference somewhere?

Place the following statements in a batch file and run it from VS Command Prompt
BTSTask AddResource -Source:.\Assemblies\Schemas.DLL
-ApplicationName:MyApp -Type:System.BizTalk:BizTalkAssembly
-Options:GacOnImport,GacOnInstall -Overwrite
BTSTask AddResource -Source:.\Assemblies\Orchestrations.DLL
-ApplicationName:MyApp -Type:System.BizTalk:BizTalkAssembly
-Options:GacOnImport,GacOnInstall -Overwrite
BTSTask AddResource -Source:.\Assemblies\SharedLib.DLL
-ApplicationName:MyApp -Type:System.BizTalk:Assembly
-Options:GacOnImport,GacOnInstall -Overwrite
BTSTask ExportApp -ApplicationName:MyApp -Package:MyApp.msi
You get an MSI at the end, which you would need to import!
This addresses your problem.

I don't believe there's a solution from adding a resource to the BizTalk application automatically.
I usually use scripts to deploy to BizTalk and so I add resources as part of those (but, to be fair, I usually have more than 2 assemblies); BTSTask is the BizTalk command line utility that you can use to do that (or, if you're using MSBuild you can use the "SDC tasks"

Related

What is the .exe file that VS generates via .NET Core self-contained deployment?

[I'm using Windows conventions for convenience but this is an x-platform question.]
When I publish a .NET Core project (named, say, Tannery) via SCD, Visual Studio generates the application file publish\Tannery.exe, which is my entry point into publish\Tannery.dll. In addition, from what I've tested, publish\Tannery.exe automagically works with any config/build of Tannery.dll [on the target runtime].
This suggests Tannery.exe is just a thin wrapper around dotnet.exe and tantamount to dotnet Tannery.dll. However, I can't find documentation on this. So, what "is" this application file, and how flexibly can one use it?
When you use SCD you build your project for a specific runtime (e.g. windows x64), the build would include all the dotnet dependencies, so when you run your SCD on a system without the dotnet SDK, it will run without problem.
You can think about it as a wrapper around dotnet.exe, where the dotnet.exe is part of the build and not a system dependency.

`FileNotFoundException` when running test(s) in VS2013

I upgraded to Visual Studio 2013 after using VS 2012.
In VS 2012, when created new Test Project and add files to be "Copy Always" the visual studio copied them into bin/debug and while running the current directory(Environment.CurrentDirectory) was "bin/debug".
In VS 2013 the current directory is "TestResults/something+guid" and VS 2013 is not copying the files to this folder so an "file not found" exception thrown.
How do I change back the current directory to bin/debug in VS2013 to be like VS 2012?
Thanks!
The proper way to handle this scenario is to use DeploymentItemAttribute or test settings config to include the file(s) you want. It is this way because not all tests require the same files, different tests may require different configs entirely, or you may have several test runs and would need to inspect test artifacts to understand why one run failed and another succeeded (where the only difference was a referenced assembly, or a loose file.) Further, when run in a hosted environment (Team Foundation Server, for example) this same pattern is used on the agent server(s), writing a test to set current directory would fail when run on something like a TFS test agent.
As an aside, the path you see during a test is not actually VS2013, it's the MS Test Agent itself (a second process runs tests for sandboxing purposes, I beleive it has been this was since VS2010.)
It sounds like you have an additional problem, all but guaranteed to be one of the following. Without seeing the exception detail I'm making a best guess, these are in order of likelihood:
You have a loose file such as "test.txt" included in your test project and you have a DeploymentItemAttribute decorating your test method. But the "Copy to output folder" setting for "test.txt" is set to "Do not copy".
Changing this setting, rebuilding, then retesting should work.
You have a missing assembly reference, likely for a non-BCL assembly (or, more specifically, you're missing a reference to an assembly which is referenced by an assembly you are referencing.)
To fix this problem you should load fuslogvw.exe and use the log data to discover any missing assembly reference(s) to your test project.
You have referenced a native DLL or assembly which is compiled for a specific processor architecture (x86 vs x64 vs MSIL) and it cannot be loaded within the processor architecture which MS Test Agent is running.
The solution to this is to use an assembly with the correct processor architecture when running the test.
Between project references, "Copy to output directory" setting, and [DeploymentItem], your tests should be finding the file(s) they rely on.
Let me know if you need more info, if you're still having a problem i would suggest editing the question to include the exception detail (or at least the parts that matter, such as Type, Message and the first 5 lines of StackTrace.)

Building MSI from TFS Build

I am trying to build MSIs in a TFS Build by shelling out to DEVENV.exe (since MSBUILD does not support VSPROJs). In any case, my first installer project builds fine, the second one fails. If I reverse the order, same thing happends (i.e. the error does not follow the project). Looking at the output, I get the following errors:
Deserializing the project state for project '[MyProject].dbproj'
[MyProject].dbproj : error : Error HRESULT E_FAIL has been returned from a call to a COM component.
Also, I get:
Package 'Microsoft.VisualStudio.TestTools.TestCaseManagement.QualityToolsPackage, Microsoft.VisualStudio.QualityTools.TestCaseManagement, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' failed to load
It looks as though the first build tries to serialize the DB project (and it says it succeeds, but there is no DBML file anywhere). Then the second build tries to deserialize the DB project and fails.
I've tried resetting env settings (using the /resetusersettings flag) as well as using the /resetskippkgs flag. Nothing works.
Any ideas?
When you shell out to DevEnv, are you building that specific project (.vdproj file), or are you building the solution? It sounds like VS is trying to open the solution on the build machine and the database and test project systems aren't present.
Have you considered porting your setup project to WiX?
Start simple. Unless you're well versed in the problem you're trying to solve it's usually best to try it "by hand" before getting it running as part of a TFS build. RDP into the build server and try running the necessary commands at the command line and see what happens. You can even go simpler than that and RDP into the build machine and load Visual Studio and build it.
Bottom line is that if you can't get it to build within Visual Studio or at the command line by calling devenv.exe it won't work as part of the team build.
I am using the below Exec task to do precisely what you are doing as part of a TFS build. So I know this works. Your platform and configuration may vary depending on what you're building. The nice thing about this is that you'll have a log file at C:\Temp\MSIBuildOutputLog.txt that you can analyze for additional errors and information.
<Exec Command=""C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" "$(PathToSolution)\solution.sln" /Build "Release|Mixed Platforms" /out "C:\Temp\MSIBuildOutputLog.txt"" />
One important thing to note... There is a bug in VS2010 which causes MSI generation to fail when you try to run it at the command line using devenv.exe. This took me days to find and figure out, but you need this hotfix. Worked like a charm...
http://archive.msdn.microsoft.com/KB2286556
Actually it's the deployment projects that don't support msbuild. FWIW, this is all deprecated in the next release of Visual Studio so you might want to start looking at InstallShield Limited Edition and/or Windows Installer XML now before spending too much time on dead end, broken technology. Both of these alternatives have proper MSBuild support aswell as many other improvements.
It would be perhaps better and quicker to adopt WIX (Windows Installer XML) which is the technology MS now recommends to use within VS/MSBuild/TFSBuild environment to crate MSIs.
It is relatively easy to setup and integrate within your VS Solutions. It uses XML based files to describe your MSIs and uses these files to create your MSIs when you compile.
I would start by downloading Wix from http://wix.codeplex.com/
Once installed you would be able to use the VS2010 integration of Wix based projects to create MSIs. To get started quickly simply add a new Wix project to your solution and reference the projects whose output you wish to combine into an MSI. Next you can run a tool called "Heat" which is included with Wix toolkit to generate the XML files by scanning your projects.
Once you have these XML files, add them to your Wix project and compile.

Unable to compile .NET application with referenced TLB when library is not registered

I have a C# 4.0 application that is referencing a type library from a C++ application. This is used for some secure COM interop, a question I originally had asked here.
On my development machine this second application is installed so I can compile without any issues. If I attempt to compile on our automated build server, or any machine with Visual Studio installed but without this second program, I receive the following errors and compilation fails:
Text for google:
The type or namespace name could not be found (are you missing a using directive or an assembly reference?)
Cannot get the file path for type library "guid...." version 1.0. Library not registered. (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED))
The referenced component 'SecurityAgentLib' could not be found
Picture for readability:
I'm not sure how to get around this other than by installing the application that registers the actual dll that implements these types, but I don't want to do that on our build server. The code that uses these types are wrapped in a class that is never instantiated unless prerequisite checks are run to verify the app is actually installed, so there is no chance of a runtime error. In fact I can run my app just fine on a machine without the second app installed - I just can't compile it there.
In visual studio the reference points to the .tlb file which is included in the solution directory, so the tlb file itself is present.
I can't imagine it should work this way, and I've searched around, but I'm apparently not searching for the right terms.
EDIT:
Running tlbimp.exe generates a dll but the type library should be sufficient for compilation, I thought at least. There is also an issue of broken references. I was reading this article Troubleshooting Broken References and it says that if the reference was to a COM component that is not installed than installing the component corrects the error, which is true.
Installing it on the build server really isn't an option. Opening visual studio and re-adding a reference if the path was broken doesn't work either.
I was able to use tlbimp to create a dll and used visual studio add a reference to that dll. That let me compile, but how would this work in an unattended build server?
EDIT
Okay I came up with two solutions that worked given my requirement of this all being unattended
Ran tlbimp to create a dll from the type library. I removed the reference to the tlb from my project and added a reference to the dll itself. When the source code was copied over to a new computer it compiled without issues.
In this scenario ideally we would checkout from SVN on the build server and copy the latest DLL from the second project, then compile this project.
I also removed the tlb and added the dll in visual studio and did a diff on the .csproj file. I don't see any downside to just having a reference to the dll instead of the tlb but if needed the build server could make modifications directly to this file to remove the tlb section and add a reference to the dll following a build of the second product.
Here are a couple options that each worked.
Ran tlbimp to create a dll from the type library. I removed the reference to the tlb from my project and added a reference to the dll itself. When the source code was copied over to a new computer it compiled without issues.
In this scenario ideally we would checkout from SVN on the build server and copy the latest DLL from the second project, then compile this project.
I also removed the tlb and added the dll and did a diff on the .csproj file. I don't see any downside to just having a reference to the dll instead of the tlb but the build server could make modifications directly to this file to remove the tlb

NUnit tests in a separate project, same solution

I have a solution containing my main project and a test project using NUnit. Everything compiles but when I run NUnit I get the exception below after the tests load, and the tests fail. I've added the main project as a reference, and I have $(ProjectDir)bin/Debug/$(TargetName)$(TargetExt) in the arguments for NUnit in the external tools setup, with a blank initial directory.
MyMainProjectTests.Database.TestAddDelete:
System.BadImageFormatException : Could not load file or assembly 'MyMainProject,
Version=1.1.1.0, Culture=neutral, PublicKeyToken=null' or one of its
dependencies. An attempt was made to load a program with an incorrect format.
TearDown : System.Reflection.TargetInvocationException : Exception has been
thrown by the target of an invocation.
----> System.BadImageFormatException : Could not load file or assembly
'ChickenPing, Version=1.1.1.0, Culture=neutral, PublicKeyToken=null' or one
of its dependencies. An attempt was made to load a program with an incorrect
format.
After scouring for hours the only thing I've found is a bug in VS2005 which mentions the /bin and /obj directories, but the answer provided didn't help.
Any solutions?
Instead of setting up NUnit as an External Tool, I set the unit test project as the StartUp project. In the project's Properties screen, set the Start Action to "Start external program" and point it to nunit.exe. In the Start Options section, I specify the test assembly (no path necessary) in the "Command line arguments" box. At this point, simply press F5 to start up NUnit.
Use the nunit-x86.exe instead of nunit.exe as your runner.
A better longer term solution may be to buy ReSharper that includes a much nicer test runner for NUnit that fully integrates into Visual Studio. It auto detects your .NET project type (x68 or x64). ReShaper comes with tons of other features of which unit testing is just one. Their test runner also integrates with their DotCover code coverage analyser.
You may find that you'll need a later version of Visual Studio to use ReSharper. The latest version works with Visual Studio 2013 Community Edition that you can get for free though I understand you may have issues upgrading some project features from such a rather old VS2005 project.
I don't have any affiliation with ReSharper.
Are you running on x64? You will get that error if loading a x64 bit from x86 and vise versa. Also, the path you are trying to create should be the $(TargetPath) macro.
Just set "Platform target" of Tests project to "x86".
Is your main project a .exe or a .dll? Older versions of .NET couldn't reference an .exe, so that might be the problem.
In either case, I'd expect problems if the main assembly didn't end up somewhere accessible by your test assembly (for example, in the same directory). You could check that, and if not make it so, perhaps by having Visual Studio copy the referenced (main) assembly to the local directory.
The "An attempt was made to load a program with an incorrect format." makes me wonder if the "missing assembly" theory is right, but without more info, it's the best guess I can think of.
Go the the NUnit install (example: C:\Program Files (x86)\NUnit 2.6.3\bin) location and open nunit-86.exe.

Resources