Class is not found in SQL assembly - sql-server-2005

I am trying to make my first CLR Assembly\stored procedure. I have compiled the code using CSC, and added the assembly to SQL server. The assembly shows up, but the class seems to be missing.
C# CODE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Server;
namespace TextFunctions
public class RegularExpressions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static string RegExReplace(string input, string pattern, string replacement)
{
Regex Reginstance = new Regex(pattern);
return Reginstance.Replace(input, replacement);
}
}
END C# CODE
CREATE FUNCTION CODE
CREATE Function RegExReplace(#Input NVARCHAR(512),#Pattern NVARCHAR(127), #Replacement NVARCHAR(512))
RETURNS NVARCHAR(512) EXTERNAL NAME RegEx.RegularExpressions.RegExReplace
ERROR
Could not find Type 'RegularExpressions' in assembly 'RegEx'.
1) Can you see what I am doing rough?
2) Is there a table or view in sql server that lets me see the classes and functions inside an assembly?

According to your code snippet your RegularExpressions class is in the TextFunctions namespace.
Changing your T-SQL code to use TextFunctions.RegularExpressions.RegExReplace should fix it.

Related

Trying to use C# DLL with ComVisible attribute set from unmanaged C++

TL;DR: I'm trying to use a C# library in C++. Why am I getting an undeclared identifier error when trying to use an identifier from my .tlh file? There must be tons of examples out there, but I haven't been able to find any that include both the C# and C++ code, and that work. Links to such examples would be greatly appreciated.
I have the following classes defined in C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using CrystalDecisions.CrystalReports.Engine;
namespace CapsCrystalReportLib
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("B4E5F784-12E6-4311-9BB9-D5B3252F20A3")]
public interface ICapsCrystalReport
{
[DispId(1)]
void DisplayReport(string fileName);
[DispId(2)]
void PrintReport(string fileName);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("89402DE5-BA26-4AC0-AB40-00ADD2876FF4")]
[ProgId("CAPSCrystalReport.Report")]
[ComDefaultInterface(typeof(ICapsCrystalReport))]
public class CapsCrystalReport : ICapsCrystalReport
{
public void DisplayReport(string fileName)
{
MessageBox.Show("Displaying report " + fileName);
}
public void PrintReport(string fileName)
{
MessageBox.Show("Printing report " + fileName);
}
}
}
I have the following C++ program attempting to use this class:
#include "stdafx.h"
#import "W:\\CAPS Builds\\trunk\\CapsCrystalReportLib\\bin\\Debug\\CapsCrystalReportLib.tlb" no_namespace
int _tmain(int argc, _TCHAR* argv[])
{
// Initialize COM.
HRESULT hr = CoInitialize(NULL);
// Create the interface pointer.
CapsCrystalReport CRPtr(__uuidof(CapsCrystalReport));
long lResult = 0;
// Call the Add method.
CRPtr->DisplayReport("SomeReport.rpt");
// Uninitialize COM.
CoUninitialize();
return 0;
}
I am getting an undeclared identifier error. The compiler doesn't know what a CapsCrystalReport is. What am I doing wrong?
P.S. I took another look at the sample I copied this from. One of the comments asks the same question, and it was never answered.
You were very close, but CRPtr is a COM interface reference (=pointer) so it must be declared like this:
ICapsCrystalReportPtr CRPtr(__uuidof(CapsCrystalReport));
The IxxxPtr class was generated for you by #import in a .tlh file. What you can do when you have issues with #import, is just open the generated .tlh file and look at it.
Note you don't have to declare a default interface in C#, you can just declare the class like this:
[ComVisible(true)]
[Guid("89402DE5-BA26-4AC0-AB40-00ADD2876FF4")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("CAPSCrystalReport.Report")]
public class CapsCrystalReport
{
... same ...
}
And in C++, you would have to adapt your imports like this:
#import "C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\mscorlib.tlb" auto_rename
#import "W:\\CAPS Builds\\trunk\\CapsCrystalReportLib\\bin\\Debug\\CapsCrystalReportLib.tlb" no_namespace
and you would use it like that (the interface was implicitely created by .NET and wrapped by the #import):
_CapsCrystalReportPtr CRPtr(__uuidof(CapsCrystalReport));
PS: I would recommend you to keep the namespace, avoid no_namespace because it can cause problems with collisions especially in C++.

How do I find the file containing a ComVisible class registered using regasm?

I have written a class in C# and marked it ComVisible. I uploaded it to my customer's computer and registered it using RegAsm. But when I try to use it from a Python script, I get an error saying "The system cannot find the file specified." If I replace the name of the class with "ThisDoesNotExist.ReportEngine", the error message is "Invalid class string", which is what I would expect. So, it appears that the Python script found the class name ("CrystalReportsRT2.ReportEngine", in case anyone cares) in the registry, but could not find the DLL file containing that class.
If I was working with an old-fashioned COM object, I could find the class name in the registry, note its CLSID, find the registry entry for that CLSID, and file name from the InProcServer32 key. But for a class registered using RegAsm, the InProcServer32 key only contains the class name and other assembly information. How can I find out what file is being looked for so I can verify its existence? Or do I have to add the assembly into the Global Assembly Cache?
I was trying to get a modified version of an existing library to work. I decided to try a brand-new library. I tried this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RegAsmTest
{
[Guid("E476213F-1D62-408C-B89E-D9A8B4814CE1")]
[ComVisible(true)]
public interface ITest
{
int DoSomething(int input);
}
[Guid("C1E26B60-7D25-4EFE-80E9-F958024E22ED")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
[ProgId("RegAsmTest.Test")]
public class Test : ITest
{
public int DoSomething(int input)
{
MessageBox.Show(string.Format("Input was {}", input));
return input;
}
}
}
And I tried using it from Python:
import win32com.client
try:
TestObject = win32com.client.Dispatch("RegAsmTest.Test")
print ("Object created.")
except Exception as ex:
print ("Failed to create object: " + str(ex))
At first I got "Class not registered". I checked to see if I had "Register for COM Interop" checked, and I hadn't. I checked it. I got another error. (I'm sorry, but I've forgotten which.) I tried running RegAsm with /tlb, and I got "System cannot find the file specified." I tried unregistering the library, and got "Invalid class string" where I would have expected "Class not registered". I tried re-registering without /tlb, and got "System cannot find the file specified".
So, I've got three different errors, and I do not know what sequence of operations or missed operations cause them:
Class not registered
Invalid class string
System cannot find the file specified
What do I have to do?

Xamarin Custom Panels: Size type missing. What references do I need?

I've been following some tutorials to learn Xamarin/Xaml. I'm currently looking at custom panels.
My custom Panel class is currently as follows:
using System;
using System.Collections.Generic;
using System.Text;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
public class MyCustomPanel : Panel
{
protected override Size MeasureOverride(Size size)
{
return base.MeasureOverride(size);
}
}
With this code i get:
The type or namespace 'Size' could not be found (are you missing a
using directive or an assembly reference?)
Intellisense tells me (hovering over the base MeasureOverride) that the type of Size I'm looking for is Windows.Foundation.Size however I'm already using Windows.Foundation. It does not have a type of Size.
If I try to resolve with intellsence the only Size types availble to me are System.Drawing and Xamarin.Forms. None of these are suitable for MeasureOverride.
Can anyone help with this? What is it that I am missing?
Thanks in advance.

What is the C++ code to switch from a Main XAML form to a second XAML form

I am using visual studio 2015.
I am creating an app that has several forms, but I am stuck because I don't know the code to switch pages.
The MainPage.cpp file code is =
//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include "IncomeForm.xaml.h"
using namespace pman_project2;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
MainPage::MainPage()
{
InitializeComponent();
}
void pman_project2::MainPage::Income_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
??????????????????????????????????????
}
The row of question marks is where i am stuck. I have looked online and it tells me how to do it in c# but not c++.
apparently the code in c# is
this.Frame.navigate(typeof(page.IncomeForm));
can anyone help?
Also use this method, but in C++/CX way:
Tip If you are programming using a .NET language (C# or Microsoft Visual Basic), the TypeName type projects as System.Type. When programming using C#, it is common to use the typeof operator to get references to the System.Type of a type. In Visual Basic, use GetType. If you're using C++/CX, where you'll need to create a TypeName helper struct, you can use the typeid component extension.
void pman_project2::MainPage::Income_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(IncomeForm::typeid));
}
For advanced usage, please see this sample
Share my sample, please check: Link

.NET 4.5.1 WCF Serialization exception

Our LOB application is a client server application which uses CSLA business objects, those business objects are being serialized using the NetDataContractSerializer. The server side is running on WCF and the client has endpoints.
This all works when the client software is running from Windows 7 or Windows 8 having .NET 4.5 installed.
When running the client software on Windows 8 or Windows 8.1 with the latest .NET 4.5.1 Framework the following exception occurs.
The formatter threw an exception while trying to deserialize the
message: There was an error while trying to deserialize parameter
http://ws.lhotka.net/WcfDataPortal:FetchResult. The InnerException
message was 'Error in line 1 position 11619. 'Element'
'm_serializationArray' from namespace
'http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not
expected. Expecting element 'm_keyRehashCount'.'. Please see
InnerException for more details.
The most inner exception is
Error in line 1 position 11619. 'Element' 'm_serializationArray' from
namespace 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
is not expected. Expecting element 'm_keyRehashCount'.
I cannot find anything about this on stackoverflow or on google, i have posted this same question on the CSLA forums and perhaps i should also post it on Connect. But maybe i'm lucky here?
I need some time to backup my development environment before i update the .NET Framework to 4.5.1
I can think of two possible solutions:
upgrade the 2008 server to .NET 4.5.1.
force the client software to use .NET 4.5
Is it possible to force the client software to use .NET 4.5 only?
Any other idea's?
I can reproduce this issue from my end. I would like to give a few facts to see if this would help you in the meantime.
NetDataContractSerializer is more restrictive than a DataContractSerializer as per the documentation.
The NetDataContractSerializer differs from the DataContractSerializer in one important way: the NetDataContractSerializer includes CLR type information in the serialized XML, whereas the DataContractSerializer does not. Therefore, the NetDataContractSerializer can be used only if both the serializing and deserializing ends share the same CLR types.
I believe the type ConcurrentDictionary in 4.5.1 has added a property or member variable named m_keyRehashCount which is not found in the 4.5 version of the ConcurrentDictionary. While trying to de-serialize this object on a 4.5.1 machine – the serializer expects this missing property resulting in this exception.
<m_keyRehashCount>0</m_keyRehashCount>
Here are a few ways to solve this problem:
Upgrade your server machine as well to 4.5.1. .net 4.5.1 is a free upgrade to .net 4.5 which also has fixes for some compat issues found in .net 4.5.
Use DataContractSerializer instead of NetDataContractSerializer as this
does not expect the exact same CLR types at both serializing and
deserializing ends.
Change to use Dictionary instead
of a ConcurrentDictionary as I see this type works
fine.
If you have previously serialized objects (serialized with pre 4.5.1) which contain ConcurrentDictionary you can deserialize it in 4.5.1 using the following example.
This example only help deserializing already serialized ConcurrentDictionary objects by creating new class which can deserialize using the ConcurrentDictionary serialization XML, see also other answers.
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using ClassLibrary1.Model;
namespace SerializaerDesrializer
{
[DataContract]
public class CompositeDictionaryHolder
{
// Old serialized data member:
//[DataMember]
//private MyConcurrentDictionary<int, string> _concuurentDictionary = new MyConcurrentDictionary<int, string>();
private ConcurrentDictionary<int, string> _concuurentDictionaryInternal = new ConcurrentDictionary<int, string>();
[DataMember]
private InternalArray _concuurentDictionary;
public CompositeDictionaryHolder()
{
// Just an example:
_concuurentDictionaryInternal.TryAdd(1, "1");
_concuurentDictionaryInternal.TryAdd(2, "2");
_concuurentDictionaryInternal.TryAdd(3, "3");
}
/// <summary>
/// Get the data array to be serialized
/// </summary>
[OnSerializing]
private void OnSerializing(StreamingContext context)
{
// save the data into the serialization array to be saved
_concuurentDictionary = new InternalArray(_concuurentDictionaryInternal.ToArray());
}
/// <summary>
/// Construct the dictionary from a previously seiralized one
/// </summary>
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
_concuurentDictionaryInternal = new ConcurrentDictionary<int, string>(_concuurentDictionary.m_serializationArray);
}
}
[DataContract(
Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")]
public class InternalArray
{
public InternalArray()
{
}
public InternalArray(KeyValuePair<int, string>[] serializationArray)
{
m_serializationArrayInternal = serializationArray;
}
[DataMember]
public KeyValuePair<int, string>[] m_serializationArray
{
get { return m_serializationArrayInternal; }
set { m_serializationArrayInternal = value; }
}
private KeyValuePair<int, string>[] m_serializationArrayInternal;
}
}