Visual Studio variables not being transformed when generating code via TDS - sitecore

When referencing an assembly inside a .tt T4 template, I should be able to use the following declaration:
<## assembly name="$(SolutionDir)\..\..\Build\lib\HedgehogDevelopment.CodeGeneration.Extensions.dll" #>
From what I can see, the SolutionDir is not being transformed, and I get an error message (below)
Note: The HedgehogDevelopment.CodeGeneration.Extensions.dll cannot be added to the GAC or the Visual Studio assembly folder as the DLL needs to passed along with the project.
I don't know how the TDS code generation is executed, so I am asking here to see if someone has resolved something similar.
Error | 10 |The host threw an exception while trying to resolve the
assembly reference
'$(SolutionDir)......\Build\lib\HedgehogDevelopment.CodeGeneration.Extensions.dll'.
The transformation will not be run.
The following Exception was
thrown: System.IO.FileLoadException: The given assembly name or
codebase was invalid. (Exception from HRESULT: 0x80131047) at
System.Reflection.AssemblyName.nInit(RuntimeAssembly& assembly,
Boolean forIntrospection, Boolean raiseResolveEvent)
at
System.Reflection.AssemblyName..ctor(String assemblyName)
at
Microsoft.VisualStudio.TextTemplating.GlobalAssemblyCacheHelper.GetLocation(String
strongName) at
Microsoft.VisualStudio.TextTemplating.VSHost.TextTemplatingService.ResolveAssemblyReference(String
assemblyReference) at
Microsoft.VisualStudio.TextTemplating.Engine.ResolveAssemblyReferences(ITextTemplatingEngineHost
host, TemplateProcessingSession session)

Make sure you add HedgehogDevelopment.CodeGeneration.Extensions.dll to either the GAC or the Visual Studio Assemblies folder:
https://github.com/HedgehogDevelopment/tds-codegen/wiki/Using-Extension-Methods
Or use the full path to the assembly in your directive.
UPDATE:
As an update to this, the extension methods have now been moved into T4 files so you no longer need to deploy the DLL to the GAC or Visual Studio folder. You can find the updated files in the Github repo.

Related

ResolveAssemblyReference cannot find dll and I cannot force it to look where it is

I have solution with n csharp projects and cpp project on top, this cpp provides interfaces and headers so those csharp ones can be used in other cpp solutions.
The build machine is configured to build csharp project with anyCPU architecture so it provides single assembly per build in Solution\bin\Release. For cpp the anyCpu is not available so I build project twice and store assemblies in Solution\bin\Release\x86 and x64 folders.
This is all to get it packaged in nuget as a single package with .targets file to ease consumption in other cpp projects.
Issue is that cpp project is looking for csharp asseblies using ResolveAssemblyReference and cannot find it, giving missleading message:
ResolveAssemblyReferences:
Primary reference "Implementation".
Could not find dependent files. Expected file "C:\Jenkins\Workspace\Solution\bin\Release\x86\Implementation.dll" does not exist.
Could not find dependent files. Expected file "C:\Jenkins\Workspace\Solution\bin\Release\x86\Implementation.dll" does not exist.
Resolved file path is "C:\Jenkins\Workspace\Solution\bin\Release\x86\Implementation.dll".
Reference found at search path location "".
I tried to alternate ResolveAssemblyReferences behaviour using command line properties, custom targets/properties, but without any luck. The parameters described in https://learn.microsoft.com/en-us/visualstudio/msbuild/resolveassemblyreference-task?view=vs-2017 seem to be computed during the build process and I cannot inject any value, which should be in this case something like $(OutDir)..
The one feasable solution seems to be copy c# dlls into each cpp folder, but I dont think it is the way to solve it properly.
Closes I got is by using /p:ReferencePath like below:
"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MsBuild\15.0\bin\MsBuild.exe" /p:BuildProjectReferences=false /p:Configuration=Release /p:DebugType=full /p:DebugSymbols=true /p:PlatformToolset=v120 /p:WindowsTargetPlatformVersion=8.1 /p:ForceImportBeforeCppTargets="C:\Jenkins\Workspace\Solution\Cpp.props" /p:OutDir="C:\Jenkins\Workspace\Solution\bin\Release\x86\" /p:Platform=Win32 /t:Build Interface\Interface.vcxproj /p:ReferencePath="C:\jenkins\workspace\Solution\bin\Release"
My custom Cpp.props does:
<Target Name="Output" BeforeTargets="ResolveAssemblyReferences">
<Message Text="AssemblySearchPaths: $(AssemblySearchPaths)" />
</Target>
and by adding /p:ReferencePath it got added to AssemblySearchPaths as second record, after {CandidateAssemblyFiles}; but it is still not finding those dlls

Issu using startMATLAB in C++ with "MatlabEngine.hpp" in r2017b

In its new version 2017b, Matlab has released a new MATLAB Engine API for C++: https://fr.mathworks.com/help/matlab/calling-matlab-engine-from-cpp-programs.html
When I try to use this API, (only to start Matlab at the beginning !!), I have an issue using :
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();
The compilation is ok, but at the execution :
Here is the call stack:
matlab::engine::initSession --> matlab::engine::startMATLAB -->
matlab::engine::startMATLABAsync --> engine_create_session
Now, I use a different way to do my job, but I don't want to let an issue without a solution. Can someone spot the problem with this API?
My configuration :
Matlab 2017b
Visual Studio 2017
Windows 10
Just a few days back, I had the same issue: here
So, I had raised a ticket in MATLAB for technical support. And they suggested to build the project in the following manner which works for me:
Create a project and add the source file.
Go to the project properties, and do the following changes(Make sure to change the architecture to X64):
Under C/C++ General, add the following directory to the field
ADDITIONAL INCLUDE DIRECTORIES: C:\Program Files\MATLAB\\extern\include
Under C/C++ Precompiled Headers, select "Not Using Precompiled
Headers".
Under Linker General, add the directory to the field ADDITIONAL
LIBRARY DIRECTORIES: C:\Program
Files\MATLAB\\extern\lib\win64\microsoft
e. Under Configuration Properties ->Debugging Add the following 2
Target paths in the Environment: PATH=C:\Program
Files\MATLAB\\bin\win64; PATH=C:\Program
Files\MATLAB\\extern\bin\win64;
Under Linker Input, add the following names to the field marked ADDITIONAL DEPENDENCIES:
libmat.lib
libMatlabEngine.lib
libMatlabDataArray.lib
Make sure that the following directory is in the Windows system
environment PATH: C:\Program Files\MATLAB\\bin\win64;
C:\Program Files\MATLAB\\extern\bin\win64
Now, build the project and run your application.
Like in the comment, I solved the issue by upgrading Matlab from R2017b to R2018b!
I noticed the same issue testing R2020b
while it worked fine with R2020a, a run-time error occurs with R2020b when running
std::unique_ptr matlabPtr = startMATLAB();

What is the correct syntax to include or exlude test assemblies in Visual Studio Tests with Visual Studio Team Services VSTS

I have 2 test projects in my solution. I want to exclude one of them (with Selenium tests) to be excluded from the Visual Studio Test that is part of the continuous integration cycle.
The name of the generated dll is:
Ta-Tend.UITests.dll
The option "Test assembly" (form the Test Execution Options) is:
*test*.dll; -:\obj**; -***UITest*.dll
Whatever I fill in, the test is executed, while I need it to be excluded.
I cannot find anywhere the complete syntax definition for this field. Just parts of it, but they don't work.
Using this code instead:
*test*.dll;-:**\obj\**;-:**\*UITest*.dll
If Ta-Tend.UITests.dll file is in the subfolder, using
**\*test*.dll;-:**\obj\**;-:**\*UITest*.dll

Working directory of nunit tests in Visual Studio Test Explorer

I've started trying to use the Test Explorer with the nunit test adapter. The unit tests that I'm running have some test files which are loaded from a test folder, the test folder contains test files which are specific to a particular project. Running nunit manually previously, I was able to specify the working directory for the test, but I can't see how I would do that when using the test explorer. So currently I have some unit tests failing because they're unable to find these test files.
I've tried using the project macro to define in the code where the test files will reside in relation to the project directory but that's given me more issues. I've tried setting the Project $(ProjectDir) macro as a Preprocessor definition as per accessing-visual-studio-macros-from-source-code, however I'm using the compiler from visual studio 2008, so I either get Warning 21 warning C4129: ')' : unrecognized character escape sequence' fromPROJECT_DIRECTORY="$(ProjectDir)"because the backslashes in the directory structure from $(ProjectDir) or by doing PROJECT_DIRECTORY=LR"|($(ProjectDir))|" I getC2065: 'LR' : undeclared identifier` because LR doesn't exist in C++ prior to C++11.
Assuming this is C++-CLI, you could detect the assembly using something along the following lines and do a relative path from there:
Type^ type = SomeClassInYourAssembly::typeid;
Assembly^ containerAssembly = System::Reflection::Assembly::GetAssembly(type);
String^ pathTocontainerAssembly = containerAssembly->Location;

How to configure SQLite to run with NHibernate where assembly resolves System.Data.SQLite?

I am using the latest NHibernate 2.1.0Beta2. I'm trying to unit test with SQLite and have the configuration set up as:
Dictionary<string, string> properties = new Dictionary<string, string>();
properties.Add("connection.driver_class", "NHibernate.Driver.SQLite20Driver");
properties.Add("dialect", "NHibernate.Dialect.SQLiteDialect");
properties.Add("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("query.substitutions", "true=1;false=0");
properties.Add("connection.connection_string", "Data Source=test.db;Version=3;New=True;");
properties.Add("proxyfactory.factory_class",
"NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu");
configuration = new Configuration();
configuration.SetProperties(properties);
When I try to run it, I get the following error:
NHibernate.HibernateException: The IDbCommand and IDbConnection implementation in the assembly System.Data.SQLite could not be found. Ensure that the assembly System.Data.SQLite is located in the application directory or in the Global Assembly Cache. If the assembly is in the GAC, use <qualifyAssembly/> element in the application configuration file to specify the full name of the assembly.
at NHibernate.Driver.ReflectionBasedDriver..ctor(String driverAssemblyName, String connectionTypeName, String commandTypeName) in c:\CSharp\NH\nhibernate\src\NHibernate\Driver\ReflectionBasedDriver.cs: line 26
at NHibernate.Driver.SQLite20Driver..ctor() in c:\CSharp\NH\nhibernate\src\NHibernate\Driver\SQLite20Driver.cs: line 28
So it looks like I need to reference the assembly directly. How would I do this so I don't get this error anymore?
I downloaded the latest assembly from here: http://sourceforge.net/projects/sqlite-dotnet2.
Are you running 64-bit Windows?
When looking around Google, I saw several posts commenting that the SQLite dll file is built for x86, not x64.
See this post: http://codetripper.wordpress.com/2009/01/03/using-sqlite-on-vista-64-bit/
Edit: I'm not sure as of when, but I noticed today that the latest releases of System.Data.SQLite include the x64 dll. The x64 .dll is in \bin\x64.
http://sqlite.phxsoftware.com/
After adding the reference to the System.Data.SQLite assembly, I had to set copy local to true (select the assembly reference in VS and go to properties) so that the assembly is copied to the bin directory.
If you don't want to use 64bit version of System.Data.Sqlite
You can change "platform target" (in visual studio project->properties->Build) to x86.
I had the same problem, and the above solutions didn't work out for me. I think System.Data.SQLite has changed since.
Note that this problem is specific to a case respecting all of the following criteria:
using SQLite
with System.Data.SqlLite
on an x64 machine
and NHibernate (2.1.2.4 in my case)
That chunk of config in my web.config (or app.config for my unit tests) got it to work. I had to qualify the assembly to be sure he loads correctly.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly
partialName="System.Data.SQLite"
fullName="System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64" />
</assemblyBinding>
</runtime>
</configuration>
Somewhere in it's inner plumbing, during the mapping using scanned assemblies, NHibernate creates an Assembly object using it's partial name, as a string, "System.Data.SQLite". Somehow, the x86 version of the assembly got loaded.
The above configuration made sure that using the partial name to load an assembly would provide the x64 version.