I'm using Visual Studio 2012 and I wrote some CLR SQL assembly and deployed it on several SQL Servers. I added stored procedure that calls web service to this assembly, and when i tried to re-deploy my assembly, it failed on one of the servers.
I've got an error:
Cannot load dynamically generated serialization assembly. In some hosting environments assembly load functionality is restricted, consider using pre-generated serializer.
I'm creating assembly and stored procedures using script generated by VS (MySolution.MyProject_Create.sql). This script creates assembly:
CREATE ASSEMBLY [AssemblyName]
AUTHORIZATION [dbo]
FROM 0xx4D5A9(....)
WITH PERMISSION_SET = EXTERNAL_ACCESS;
But there is no command for creating XmlSerializers.dll file, so I have to copy this file to remote server, and run command:
CREATE ASSEMBLY [AssemblyName.XmlSerializers] FROM
'C:\path\AssemblyName.XmlSerializers.dll'
WITH PERMISSION_SET = SAFE
And then script XmlSerializers.dll manually to avoid copying this file to other servers.
Is this possible to change some settings so Visual Studio will generate create script for XMLSerializers.dll, too?
Go to project properties, build tab, and set "Generate serialization asssembly" to On.
Related
I have built software that is capable of exporting DTSX package automatically. This package among other objects has also a ScriptTask (C#). All are compiled and run just fine.
Now the new requirement is to call a class in that ScriptTask, which exists inside an external DLL we have built, so other applications can consume the same code. So we implemented a loading mechanism of the DLL, using reflection.
Assembly clientLib = Assembly.LoadFrom("C:\\......\\mylibrary.dll");
Type licenseCheckType = clientLib.GetType("myclass");
object instance = Activator.CreateInstance(licenseCheckType);
The code is running just fine, but there are several permission issues during deployment.
Running the package from DataTools, the package fails because cannot find the file. If I executed the DataTools as administrator is working. Still, I don't get it, as a user I should be able to browse the file.
Running the package from SQLAgent(this is important), the package fails. If I set the SQL Agent service user with "Local System" or "Administrator" user the is working.
I am looking for a way to find how I can make it work with a simple user by adding permissions to that path if necessary, but still, keep failing. I tried to set a simple domain user as SQLAgent Service account and give Full Control as a start to the directory without success.
Error: Exception has been thrown by the target of an invocation.
Implementing the loading mechanism from GAC, is working, but I would like to explore the other way as the DLL in my case, this DLL is referencing a LiteDb file in the system directory, and it would be nice to have them all together.
Assembly clientLib = Assembly.Loadm("mylibrary");
Type licenseCheckType = clientLib.GetType("myclass");
object instance = Activator.CreateInstance(licenseCheckType);
As a summary:
Using the GAC
UI will reference the local DLL because exist in bin folder
SSIS will reference the GAC DLL because of loading from GAC, which references a db file from local folder
Using the Local (problematic)
UI will reference the local DLL because exist in bin folder
SSIS will reference the local DLL because of loading from local folder, which references a db file from local folder
I've created a SSIS package (SQL Server Data Tools for Visual Studio 2013) for importing some data. Long story short, I need to embeed some dlls to be called in runtime using this method:
Embedding assemblies inside another assembly
Tried outside SSIS script component and is working.
Problem is, when you try to add a .dll as a resource the package gets corrupted and throws
Is there any workaround to use custom assemblies into a SSIS package without deploying them or fix this error?
Thank you
Looks like the problem is because the .dll is stored as bytes in the XML file of the package, and probably finds some character not allowed.
The workaround was transform that .dll into a Base64String, embeed it as a resource on the project and then do the way back.
I have a remote SQL Server database, wrapped with Entity Framework inside a dll.
When I reference that dll from my main application, I get a runtime exception stating "missing connection string in app.settings file" or, if I manually add the connection string, "no Entity Framework engine found".
If instead, I install EF from NuGet ALSO in my main application, the referenced dll works perfectly.
Now, the reason why I created and referenced the dll was to detach my business layer from the persistence layer, but if I need anyway a reference to EF for my application to work, I'm loosing the advantage of the dll wrapping.
What should I do?
EDIT:
I can't add a dependency from my main app to EF simply because the user of that dll will be a client outside .NET, such as an Excel or Matlab instace
You will have the same issue with all your dependencies. You must distribute multiple DLLs and make sure they get loaded. See
See Resolving Assembly Loads
The AssemblyLoad event allows you to take over the assembly loading process for your AppDomain, and you can find the dependent assemblies on disk outside of the normal search locations (which are dependent on the host .exe location), or download them, or unpack them from assembly resources in your main .dll.
See also How to load an Assembly in a SSIS script task that isn’t in the GAC
The dll NEVER has it's own config file that it accesses to read settings such as connection strings. Although your code to read the config information may be in an assembly, the config file is owned by the host process, so an entry for connection strings MUST be present in the Host processes config file.
In your scenario, it sounds like on the remote sever it will be SQL server that acts as the host process. On your local machine, the host process (your .exe or website, IIS Wp3 ) will act as the host process. Your local process WILL require the connectionstring setting in web.config / app/config.
In VS, when we add a reference to an assembly project, all of the dependent .dll's get compiled and placed in the top level applications bin folder. If you simply reference a .dll file from your application, these dependent .dll files are not placed in the bin folder. This is what you are experiencing here with EF.
It is possible to encapsulate EF functionality inside a .dll file, but the .dll files which make up EF itself, MUST be available to the host process. You don't need to add a NuGet reference to your main application. By referencing the project that you .dll is built from in your main application, the EF engine will be compiled to the bin folder of your main application.
Once you have built and deployed your main application with a project reference to your assembly, all the required files will be in the folder from which you execute your application. You can then make changes to the .dll source and just update the .dll binaries in the application folder, providing the changes do not break contracts etc eg. method signatures.
How can i have 'Create Assembly' reference the build output path.
I have an SQL CLR that references a web service.
I have an entry in the PostDeployment script
CREATE ASSEMBLY TestWebServiceClientXML from N'\\TestServer2012\clrdeploy\Test\TestWebServiceClient.XmlSerializers.dll' WITH permission_set = EXTERNAL_ACCESS
Currently this works fine. I build the TestWebServiceClient separately manually, that builds the dll and XMLSerializer dll to a share that SQL can see. When i then publish the database project with the CLR in that references this, the PostDeployment scripts uses the XMLSerializers dll I've just built from the share.
How can I get this scenario to work with a build server? All the build outputs, including the XMLSerializers dll will go to a single build output path on the build server and when the post deployment script runs it will create an assembly from an old version on the share '\TestServer2012\clrdeploy\Test\' as this is hard coded, not the version just built.
Eventually I want this to run within Release Management. Anyone done this before?
Using SQLCMD variables, have the build server pass the build folder's path to SqlPackage.exe as a SQLCMD variable. Then modify your post deployment script to look something like this:
CREATE ASSEMBLY TestWebServiceClientXML from N'$(BuildFolder)\clrdeploy\Test\TestWebServiceClient.XmlSerializers.dll' WITH permission_set = EXTERNAL_ACCESS
I've been creating various plugins for an application that requires me to produce a .tlb file. In the past, it has simply been a case of configuring my project's build properties to 'Register for COM interop' thereby producing a .tlb file along with my output dll. Previously, when using the Visual Studio 2010 installer projects template, this would always correctly register .tlb during installation on the target machine.
I've recently attempted to make the switch to Visual Studio 2012 and use the InstallShield LE project to produce my installer, but it doesn't seem to register the type library during the install, nor does the express addition seem to allow me to manually register via the cmd-line regasm route - or at least it's not that obvious to me.
In the InstallShield project options I had to manually add the .tlb application file (from the build's \release folder) to the list of files to be included in the installer as it doesn't seem to get included along with the files produced by the project output or content options. In the .tlb file's 'COM & .Net Settings' properties, I have it configured to Registration Type: 'Extract COM Information' and have enabled 'COM Interop'.
What am I missing?
Try this thread for a good technical description: Are *.tlb files ever used at runtime?
In most cases I believe the *.tlb file is not needed because it is already compiled into most binaries regardless of whether it is an exe file or a dll, but .NET Interop is a lot more complex and as the other thread explains the *.tlb file can be needed to deal with advanced communication issues between threads and processes - something that I incidentially had forgotten.
When implementing a setup I have never had the need to register a *.tlb file by itself, it has been enough to register the corresponding binary (exe/dll), but this all depends on the use cases for the product.
Be aware that the way Installshield is registering for COM Interop is not always the best option as far as I recall. I am not sure exactly what they are doing, but I would check and compare with a normal regasm.exe registration:
http://msdn.microsoft.com/en-us/library/tzat5yw6(v=vs.110).aspx . And read the linked thread (Are *.tlb files ever used at runtime?) carefully on the issues of proxies, stubs and marshalling in case you need these features supported.
Here are some further links with concise information on COM/DCOM:
Contents of a Type Library:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms221355(v=vs.85).aspx
COM, DCOM, and Type Libraries: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366757(v=vs.85).aspx
Files Generated for a COM Interface: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366830(v=vs.85).aspx