Hello I'm trying to compile my C# code into a .dll file to be used client-side in a VBA script.
My C# code references a SOAP Webservice and isn't behaving well. When I run csc /target:library file.cs I get the following errors CS0234 on com, and CS0246 BbsSecurityContext,BbsEntityResult (Classes within the webservice). It says that the com namespace does not exist in namespace SOAPTest. Please let me know if I can supply more information.
Here is a snippet of code from the file
...
using SOAPTest.com.blueberryhosting.broadviewbbsvcstg;
using System.Runtime.InteropServices;
namespace SOAPTest
{
[Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Webservice
{
private BbsSecurityContext sc;
public Webservice(string apiKey, string sourceSystem, int userID)
{
createSecurityContext(apiKey, sourceSystem, userID);
}
...
public void getInvestors(string filepath)
{
using (BbsInteropWebService ws = new BbsInteropWebService())
{
BbsEntityResult x = ws.GetInvestors(sc);
if(x.Success)
{
generateCSV(x,filepath);
}
}
}
...
Your snippet includes using SOAPTest.com.blueberryhosting.broadviewbbsvcstg;. I suspect you recieved the error because the csc.exe command you specified included only file.cs and that namespace was not defined in the file. Most likely it was defined in another code file or a library. You need to provide all dependencies when you invoke the compiler.
Command-line Building With csc.exe
How to use references when compiling c# code via command line
Related
I'm just learning C# so I don't know if I'm just messing up the setup or what, but I used dotnet to create a new project where I'm keeping ALL of my little test scripts. I'm using VS Code as my editor. I create a path variable for csc to compile.
I can compile a Hello World project no problem, but I'm working through this course online and the next part was to make a simple gradebook.
I have GradeMain.cs
namespace Grades
{
public class GradesMain
{
static void Main (string[] args)
{
GradeBook book = new GradeBook();
book.AddGrade(91);
}
}
}
And GradeBook.cs
using System.Collections.Generic;
namespace Grades
{
public class GradeBook
{
public void AddGrade (float grade)
{
grades.Add(grade);
}
List<float> grades = new List<float>();
}
}
When I try to compile using csc I get the following error
error CS0246: The type or namespace name 'Grades' could not be found (are you missing a using directive or an assembly reference?)
My intellisense shows that my GradeBook has two references from GradeMain. I saw this post Referenced Project gets "lost" at Compile Time but since I'm not using visual studio I wasn't sure if it was related / how to check my dotnet client profile.
For me what worked is what #SLaks suggested which was to compile both files with csc.
So runing csc GradesMain.cs GradeBook.cs worked perfectly.
Hey all this is my first time creating a COM object for a classic asp page.
The process I followed when creating this COM DLL is this:
1) Used the Strong Name Tool (sn.exe) and placed the .snk file within the app. (sn -k myKey.snk)
2) Added:
[assembly: AssemblyKeyFile(#"myKey.snk")]
[assembly: ComVisible(true)]
to the AssemblyInfo.cs. I do get a warning on the KeyFile saying:
Use command line option '/keyfile' or appropriate project settings
instead of 'AssemblyKeyFile'
3) Ran the following from the Administrator: SDK Command Prompt:
tlbexp c:\\temp\\dll\\classicASPWSEnDecrypt.dll /out:c:\\temp\\dll\\classicASPWSEnDecrypt.tlb
regasm /tlb:c:\\temp\\dll\\classicASPWSEnDecrypt.tlb c:\\temp\\dll\\classicASPWSEnDecrypt.dll
gacutil /i c:\\temp\\dll\\classicASPWSEnDecrypt.dll
regasm c:\\temp\\dll\\classicASPWSEnDecrypt.dll /codebase
All registered just fine without errors.
In my classic ASP page i have:
<%
Dim classicEnDecrypt
Set classicEnDecrypt = Server.CreateObject("classicASPWSEnDecrypt.Class1")
response.write(classicEnDecrypt.Encrypt("testing"))
%>
I found that the ProgID (using OLEView) was Class1 as seen below:
And my C# code (just a snip) is this:
namespace classicASPWSEnDecrypt
{
public class Class1
{
public string Encrypt(string PlainText)
{
[code here]
}
public string Decrypt(string EncryptedText)
{
[code here]
}
}
}
Once I run the ASP page on my local machine (IIS7/Windows 7 Enterprise) I get this error:
Microsoft VBScript runtime error '800a01b6'
Object doesn't support this property or method: 'Encrypt'
/contactupdateWS.asp, line 49
Not quite sure why it says I don't have Encrypt function when I know I do?!
What could I be missing?
I already provided some information in comment.
I also feel that you should not have static method for this. It seems that com does not support static method.
http://msdn.microsoft.com/en-us/library/ms182198.aspx
Also you are creating object of class by using Server.CreateObject method so it is quite obvious that you should have instance method for this.
public class Class1
{
public string Encrypt(string PlainText)
{
[code here]
}
public string Decrypt(string EncryptedText)
{
[code here]
}
}
Hope this help.
I'm wondering how I can create a Com-Object from my own C# DLL.
I made the following Class in C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ProgressNet
{
[Guid("a9b1e34d-3ea3-4e91-a77a-5bcb25875485")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
[ProgId("ProgressNet.Server")]
public class NetServer
{
public NetServer() {}
[DispId(1)]
public string GetString()
{
return "Some String";
}
}
}
In Properties I checked Register for COM Interop.
Then I registered the DLL with regasm.
regasm G:\ProgressTestApp\ProgressNet.dll /tlb:G:\ProgressTestApp\ProgressNet.tlb /codebase
Then I tried in Progress 4GL this Code:
DEFINE VARIABLE NetServer AS COM-HANDLE.
CREATE "ProgressNet.NetServer" NetServer.
MESSAGE NetServer:GetString().
But then I get "The automation server for ProgressNet.NetServer is not registered properly"..
Any Suggestions? :)
IN case anyone is still reading this, the answer turns out to be pretty simple: The following line is wrong.
MESSAGE NetServer::GetString().
It should be
MESSAGE NetServer:GetString().
The error is in the create com-handle statement. It should be create "ProgressNet.Server" NetServer. and not "ProgressNet.NetServer" as specified by the ProgId call.
I registered the DLL with regasm as you mentioned and used the code below to test and it worked fine.
def var ch as com-handle no-undo.
create "ProgressNet.Server" ch.
MESSAGE ch:GetString()
VIEW-AS ALERT-BOX INFO BUTTONS OK.
I'm new to programming in C# (VS2010) .Net (4.0) and I'm encountering I couldn't solve by myself since some days already.
I'm using an external scripting language (Lua) in my C# code.
To do so I use LuaInterpreter built for .Net 4.0
First try:
The project is a console application -> the program works fine when I try to call a Lua class.
Second try:
The project is a class Librrary COM used from Excel -> The class library compile fine and my user defined functions work fine within Excel. But when I try to call a Lua class it crashed saying that the Lua assembly is missing.
Could not load file or assembly 'lua51, Version=0.0.0.0, Culture=neutral, PublicKeyToken=1e1fb15b02227b8a' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)
To reproduce the problem :
1- You need to get LuaInterface .Net 4.0 from
http://www.mdome.org/2011/05/16/luainterface-for-csharp-net-4-custom-build/
2- Add LuaInterface as a reference in your project
3- Copy the Lua51 DLL in the building directory (I put my Excel sheet there too)
4- Copy the code for the Class Library
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Excel = Microsoft.Office.Interop.Excel;
using LuaInterface;
namespace POC
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Functions
{
public int test()
{
Lua lua = new Lua();
return 0;
}
#region Class in Excel
[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type type)
{
Registry.ClassesRoot.CreateSubKey(
GetSubKeyName(type, "Programmable"));
RegistryKey key = Registry.ClassesRoot.OpenSubKey(
GetSubKeyName(type, "InprocServer32"), true);
key.SetValue("",
System.Environment.SystemDirectory + #"\mscoree.dll",
RegistryValueKind.String);
}
[ComUnregisterFunctionAttribute]
public static void UnregisterFunction(Type type)
{
Registry.ClassesRoot.DeleteSubKey(
GetSubKeyName(type, "Programmable"), false);
}
private static string GetSubKeyName(Type type,
string subKeyName)
{
System.Text.StringBuilder s =
new System.Text.StringBuilder();
s.Append(#"CLSID\{");
s.Append(type.GUID.ToString().ToUpper());
s.Append(#"}\");
s.Append(subKeyName);
return s.ToString();
}
#endregion
}
}
The function that crashed is the test function when called from Excel
I would take any help on that
Thanks
SInce it appears to be signed, try to put Lua51 into the GAC and see if it works. Probably you can try even by putting Lua15.dll in the same path of excel.exe.
I've had lots of issues with .NET, LuaInterface, and Lua5.1 interracting on 64-bit machines. Lua5.1 only compiles 32-bit and this requires you to (I believe) build the LuaInterface project as 32-bit as well. Try changing "Project -> Properties -> Build -> Platform Target" to "x86" in your .NET projects.
I am trying to call a C# dll from QTP (uses vbscript). I have tried a number of things with no success:
Visual Studio 2010
Create C# class libary (st.dll)
code:
using System;
using System.Collections.Generic;
using System.Text;
namespace st
{
public class Class1
{
public static int GetValue()
{
return 34;
}
}
}
regasm /codebase st.dll
fails 'because it is not a valid .NET assembly'
In QTP/vbscript, I have tried
extern.Declare micInteger, "GetValue", "e:\st.dll", "GetValue"
Returns message: 'Invalid procedure call or argument'
Regardless of QTP, I would greatly appreciate any insight on how to call the c# dll from a .vbs file.
I was able to get this working by doing the following:
Create a new C# dll in VS 2010.
namespace st4
{
public class st4_functions
{
public int GetValue()
{
return 34;
}
}
}
In QTP I added the following lines:
Set obj = DotNetFactory.CreateInstance("st4.st4_functions", "c:\\st4.dll")
MsgBox obj.GetValue()
Thanks to all that responded to my problem. Though I did not do the COM solution, it got me thinking that I could stay with .NET and led to this solution. Good job all!
EDIT:
I created a blog post to detail the steps and provide additional information:
http://www.solutionmaniacs.com/blog/2012/5/29/qtp-calling-c-dll-in-vbscript.html
As Marc said, but I think it merits an answer. If you ensure that your dll will be available though the COM mechanics, your script should be able to call into it with things like CreateObject.
How to register .NET assembly for COM interop
Your function is static. Static class members can't be matched up to interface members, and if it can't implement a .NET interface then it certainly won't implement a COM interface.