SQLCLR - Wrapping a COM call - c#

i'm trying to call a .net assembly that wraps a few COM calls (to a third party dll) from Sql Server. The assembly registers fine (i tried registering with unsafe and external access), but when i run the procedure i get this error:
A .NET Framework error occurred during execution of user-defined routine or aggregate "ManagedCodeCallTest":
System.UriFormatException: Invalid URI: The URI is empty.
System.UriFormatException:
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at System.Uri..ctor(String uriString)
at System.ComponentModel.Design.RuntimeLicenseContext.GetLocalPath(String fileName)
at System.ComponentModel.Design.RuntimeLicenseContext.GetSavedLicenseKey(Type type, Assembly resourceAssembly)
at System.ComponentModel.LicenseManager.LicenseInteropHelper.GetCurrentContextInfo(Int32& fDesignTime, IntPtr& bstrKey, RuntimeTypeHandle rth)
at ManagedCode.MyClass.ArielComponentCall()
Any ideas? Is what i'm trying to do even possible? I read something about licensed dlls but the information was very vague.
EDIT: CLR code in case it helps:
[SqlProcedure]
public static void ArielComponentCall()
{
Ariel.ApplicationClass application = new Ariel.ApplicationClass();
object arielDoc = application.OpenDocument(#"P:\Projects\COAT\Ariel1.run");
}
The project that contains this class has the reference to the com object.

The SqlClr implementation on SQL Server contains a list of "blessed" .net Assembly methods which will work within SQL Server. This is being managed through Host Protection Attributes. More precisely
SQL Server disallows the use of a type or member that has a
HostProtectionAttribute that specifies a HostProtectionResource value
of SharedState, Synchronization, MayLeakOnAbort, or
ExternalProcessMgmt. This prevents the assemblies from calling members
that enable sharing state, perform synchronization, might cause a
resource leak on termination, or affect the integrity of the SQL
Server process.
Depending on the "Access" settings of your assembly SQL Server will throw an error (when SAFE), or do nothing with the blocked method (UNSAFE and EXTERNAL ACCESS).
Unfortunately for you, the System.ComponentModel.LicenseContext class has the SharedState Host Protection Attribute and is part of the code which is not allowed. As a consequence, somewhere in your code there is a call to a method in the LicenseManager which will silently do nothing.
Either way, running com components within the SQL Server process is not a good idea as a crash in the com component will crash your entire SQL Server.

Related

Azure WebJob Throwing HttpRequestException

I'm hosting an application on Azure as a continuous WebJob. The program frequently (around once per second) makes calls to a CosmosDB database by creating a DocumentClient instance (I make use of the DocumentClient function CreateDocumentQuery and a Linq Query on the resultant IEnumerable to retrieve objects from my database). When I run the program locally it behaves as expected without any issues. When I publish the program as an Azure WebJob and run it, my logs indicate that an HttpRequestException is being thrown with the message:
An error occurred while sending the request.
Additionally, I get the following stack trace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task1.get_Result()
at Microsoft.Azure.Documents.Linq.DocumentQuery1.d__31.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at ... my calling code...
This problem only seems to occur when I make frequent use of the DocumentClient and only on the WebJob side of things. Running an equivalent load locally does not faze my application. Why is this exception occurring in my WebJob? It might be worth noting that this problem occurs with both the S1 and P1V2 App Service tiers.
DocumentClient shouldn't be used on per-request basis and instead you should use it as a singleton instance in your application. Creating client per-request will add lots of overhead on the latency.
So I'd declare Client property as "static" and initialize it in the constructor of Service. You could call await Client.OpenAsync() in the Connect method to "warm" up the client and in each of your public methods directly use the Client instance to call the DocumentDB APIs.
Dispose the Client in the Dispose method of Service.
Those clients are designed to be re-used, so it's recommended that you have a single static instance that you re-use across all functions.
Here you can find tips on performance issue:
https://learn.microsoft.com/en-us/azure/cosmos-db/performance-tips#sdk-usage
Hope that helps!

C# - error while sending email from outlook

I have a C# exe which sends email from Outlook, it works fine if run manually.
I am trying to run it through Task scheduler but it gives following error:
System.Runtime.InteropServices.COMException (0x80080005): Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
at sendMail.Program.Main(String[] args) in D:\Recovered\Root\Projects\sendMail\sendMail\Program.cs:line 20
I have found a hack. I could fix the exception but it was sending emails as Microsoft does not allow COM objects to operate through a service (in my case Task Scheduler).
I created a script and triggered command from it every few hours as needed, since it was running as a program and not a service, it works fine, the only disadvantage being sleep calls invoked from my script.
Microsoft's manual provides this:
Cause: If many COM+ applications run under different user accounts
that are specified in the This User property, the computer cannot
allocate memory to create a new desktop heap for the new user.
Therefore, the process cannot start.
WORKAROUND: To work around this problem, modify the value of the
following registry subkey:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session
Manager\SubSystems\Windows
Outlook is a singleton - COM system will refuse to marshal calls between two processes running in different security contexts.

the service instance will remain suspended until administratively resumed or terminated following error exception type initializer

I am getting the above error, exception type initializer.
Could please give what type of take an action to resolved this issue.
I got following error when am trying to drop a file in receive location and I did resumed in biztalk admin console it shows same error in event application logs.
You are getting this error due to your logging component, your logging component is trying to load itself via a static constructor most likely and failing there. It looks like it depends on Microsoft enterprise logging block, make sure you have all dependencies installed in GAC properly or check your logging component configuration to see why it's failing. It's not related to BizTalk issue.

System.InvalidCastException when creating a client activated object using an older version of an interface defined in a strong named assembly

I have a query about .Net Remoting, versioning and creating client activated objects.
Here is the scenario:
There are 2 interfaces, residing in their own assembly “SharedTypes”: IServer and IAccount. IServer contains methods “GetStatus” which returns a string, and “CreateAccount” which returns an IAccount type. This is registered into the GAC as v1.0.0.0.
Server application references SharedTypes and implements IServer and IAccount with concrete classes, Server and Account. These are MarshalByRefObject objects. The Server application marshals the Server class as a singleton object.
Client application references SharedTypes and connects to the remoteable Server object through the IServer interface successfully. Here I can call GetStatus and CreateAccount (which returns a client activated object) successfully. All OK so far.
Now I increment the version of SharedTypes to v2.0.0.0 and register into the GAC, removing the old v1.0.0.0 version.
The Server application is built against this version, but the client is not.
Now when I run the client application, it will as expected complain with a System.IO.FileNotFoundException, i.e. it could not find v1.0.0.0 of SharedTypes in the GAC.
If I copy v1.0.0.0 of SharedTypes in the exe directory of the client, the client application eventually binds to this (after GAC lookup was unsuccessful). The client application starts and I can call the GetStatus on the IServer object successfully (through the singleton object). However, if I call CreateAccount – which should return a client activated object, I get the following exception:
System.InvalidCastException: Return argument has an invalid type.
at System.Runtime.Remoting.Proxies.RealProxy.ValidateReturnArg(Object arg, Type paramType)
at System.Runtime.Remoting.Proxies.RealProxy.PropagateOutParameters(IMessage msg, Object[] outArgs, Object returnValue)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at SharedTypes.IServer.GetAccount()
My question is why does calling GetStatus on the server activated singleton object from the client (which is using v1.0.0.0) not throw this exception, whereas creating the client activated object through CreateAccount does? Since both types are created on the server, I would have thought that GetStatus call would have resulted in the same exception?
The CLR normally ensures that only one specific version of an assembly can be loaded into a process. That doesn't work in this scenario because there are two copies of the CLR at work, one on the server and one on the client. So now it is up to the remoting infrastructure to ensure that remoted type objects are compatible. Which is does with aplomb in your case. Not sure I got the question posed in your last sentence but the server is not otherwise aware of the version of the assembly loaded in the client.
Recompiling the client is required.
This may not answer your specific question, but yours is the only question I can find on StackOverflow regarding an inexplicable InvalidCastException with the message "Return argument has an invalid type" involving a server singleton.
In my case, my client started by requesting the server's singleton (i.e. the object that was passed to RemotingServices.Marshal() on the server), then in the course of its processing, it happened to get a reference to that singleton via other methods, and got this exception.
I worked around it by creating two remote-proxies for the top-level object, one to serve as the singleton, and one that could be used internally in other contexts. Perhaps it's because, in the course of client processing, it tried to get a reference to that singleton object through a different type than the one that was passed to RemotingServices.Marshal(). I'm still not sure. But having two remote-proxies for the same local object, one to serve as a remoting singleton, and one for all other internal purposes, worked around the problem. Luckily I have a stateless remote-proxy architecture, so having two for the same local-object didn't cause any trouble.
Edit: Later, I found a simpler solution, one that doesn't require two proxies -- call RemotingServices.Marshal() with the actual type of the proxy in parameter 3, instead of the interface type.
For me, client application was on .net 4.0 while server app was running on 4.5.
Installing .net framework 4.5 on client machine fixed this issue.

Error Connecting to Third Party App via COM: mscorlib Exception from HRESULT: 0x80040202

One particular user is getting an exception when connecting an application I created to a third party app using COM. The connection fails with the following error:
Source: mscorlib
Message: Exception from HRESULT: 0x80040202
This software works fine for other users.
Any ideas what could be going on?
The error occurs just before the app adds some event handlers to some of the COM objects from the third party app. It is able to successfully instantiate the objects, though.
The error code for that HRESULT is CONNECT_E_CANNOTCONNECT. This is typically returned as a failure code from IConnectionPoint::Advise because the connection point doesn't support the underlying interface.
Can you give us some more context into the code that's causing this exception? Are you creating the component, using it, etc ...

Categories

Resources