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

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?

Related

Unity importing DLL causes parser error?

I have a DLL which I am trying to import into my Unity project. I am following this tutorial on their website example. However, this line of code causes a parser error saying that "An extern alias declaration must precede all other elements."
private static extern float FooPluginFunction ();
I have tried searching online for the solution to this error but I do not get any results that are related to Unity. I have the DLL in my assets/plugins folder. Does anyone know what is causing this error and how I would fix it?
Edit: Script containing DLL import.
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class VR : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
[DllImport ("myplugin")]
private static extern TextFunc ();
myplugin.dll is in my Unity assets/plugins folder.
This error says that you have to put your dll import above that line where you use TextFunc() and inside a class.
Edit: Check this.

What is wrong with this C++ code that the school gave me?

So this is for a school project and they told us to copy and past this code for an assignment. The school I got to is more about self study so their is no real teacher assigned to help. I asked her for help and she said she would get back to me, well two weeks later and nothing.
"String" in line 5 is an error and the error says "String Undefined".
I know thats pretty specific but this code is copy and pasted so i'm not sure what to do about it.
#include "MyForm.h"
using namespace System::Windows::Forms;
[STAThread]
void main(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatible.TextRenderingDefault(false);
Organizer::MyForm form;
Application::Run(%form);
The String class is in the System namespace. You either need to fully qualify the type (System::String) or, more typically, add a using statement at the start of your program:
#include "MyForm.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]
void main(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatible.TextRenderingDefault(false);
Organizer::MyForm form;
Application::Run(%form);
}

Why no intellisense in VB6?

I wrote a DLL in C# in VS2012:
namespace COMTest
{
public class MyClass
{
public int Fun()
{
return 3;
}
}
}
And then I set "Make Assembly COM Visible=True" and in the Build page, I set "Register COM for intercrop". Then create a new VB6 project, add a reference to the generated dll file but failed……Later tried tlb file succeeded but without intellisense after saying "a." (No "Fun" tip)
Dim a As MyClass
Set a = New MyClass
MsgBox (a.Fun())
So my questions are:
1) Why must I refer tlb file instead of dll file?
2) Why no intellisense?
Try placing a check mark in:
Tools->Options->Editor->Auto List Members
If that does not help, then to resolve this problem, define a public interface by using methods and properties that you want to expose in the TLB, and then implement the interface in the class. Also, add the ClassInterface (ClassInterfaceType.None) attribute to the class. As you develop the component, you can use this approach to avoid using the ComVisible(False) attribute.
You can have more details here

.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;
}
}

Class is not found in SQL assembly

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.