I am trying to access c# method from a vb.net project.
The c# project has the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MeF.Client;
public class LoginClass
{
// lines of code that are giving errors (when commented there’s no error)
private ServiceContext context = new ServiceContext();
public string etin;
public string appSysId;
static void Main(string[] args)
{
LoginClass.CreateServiceContext();
}
//bla, bla, bla
}
The vb.net project has this:
Imports AimEFileCore
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Process As New AimEFileCore.LoginClass
Process.CreateServiceContext()
End Sub
When running the code I get the following error
System.IO.FileNotFoundException: 'Could not load file or assembly 'MeFWCFClient, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified
A Mef dll is referenced!
As soon as I comment the three lines above, it works like a charm.
I believe you need to go to Project Properties, References and check whether you have there a correct reference for referenced MeFWCFClient (a dll). You can add it within this dialogue, you might be able to use Nuget, or simply copy it to binary folder.
It looks like the method you are calling is static. Have you tried this in vb.net?
AimEFileCore.LoginClass.CreateServiceContext()
you are instantiating LoginClass but there are no public methods defined - at least not in the code you are showing, so I've assumed it contains this:
public static void CreateServiceContext()
{
...
}
as that's what the C# code would suggest.
using MeF.Client;
Thats the culprit.
Reference that DLL in your project.
Then on top add:
Imports MeF.Client
Related
I am helping convert a Visual Basic project to C#. The following is the original VB code in the Application.Designer.cs document:
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.34014
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
'NOTE: This file is auto-generated; do not modify it directly. To make changes,
' or if you encounter build errors in this file, go to the Project Designer
' (go to Project Properties or double-click the My Project node in
' Solution Explorer), and make changes on the Application tab.
'
Partial Friend Class MyApplication
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Public Sub New()
MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
Me.IsSingleInstance = False
Me.EnableVisualStyles = True
Me.SaveMySettingsOnExit = True
Me.ShutdownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses
End Sub
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Protected Overrides Sub OnCreateMainForm()
Me.MainForm = Global.ePlanSysOman.frmMain
End Sub
End Class
End Namespace
The following is code that was the result from an online VB to C# converter:
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.ApplicationServices;//I added this in
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;//I added this in
namespace My
{
//NOTE: This file is auto-generated; do not modify it directly. To make changes,
// or if you encounter build errors in this file, go to the Project Designer
// (go to Project Properties or double-click the My Project node in
// Solution Explorer), and make changes on the Application tab.
//
internal partial class MyApplication
{
[System.Diagnostics.DebuggerStepThroughAttribute()]
public MyApplication() : base(global::Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
{
this.IsSingleInstance = false;
this.EnableVisualStyles = true;
this.SaveMySettingsOnExit = true;
this.ShutdownStyle = global::Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses;
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
protected virtual void OnCreateMainForm()//I changed "override" to "virtual"
{
this.MainForm = global::ePlanSysOman.frmMain;
}
}
}
The properties that are not found are the following:
this.IsSingleInstance
this.EnableVisualStyles
this.SaveMySettingsOnExit
this.ShutdownStyle
this.MainForm
I looked each one up and I have the correct namespaces and assemblies for them. Two more issues I am having is with:
base(global::Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
//I receive the following error: "object' does not contain a constructor that takes 1 arguments
and
global::ePlanSysOman.frmMain
//I receive the following error: 'ePlanSysOman.frmMain' is a 'type', which is not valid in the given context
The VB code is error free. Only the C# code contains errors. I am not too familiar with either languages and any advice to help solve these errors will greatly be appreciated.
For VB apps, there is an "Application Framework" which is enabled by default and accessed from Project -> Properties -> Application:
All of the things from you "Not Found" list are part of that FrameWork, except MainForm. Rather than a program.cs being added to the project as in C# to show a form, VB creates an instance of the main form and displays it from designer code.
I'm trying to establish the feasibility of using our company's product with COM. To do this, I've written a (MyAppCom) dll within the solution and referenced the original (MyApp)exe project. MyAppCom creates and instance of the MyApp (mainform).
The main problem I am coming up against is that the application entry point is an application type (with settings, startup forms, etc.). Generally, this isn't so bad, but there are a couple issues that I'm banging my head against.
The app config uses the calling exes name to search for the application configuration file (i.e. if I'm calling a com instance of MyApp via Python, its looking for python.exe.config instead of MyApp.exe.config. I've sidestepped this issue for the moment by just copying the settings file, but if anybody knows how to reference this specific config settings, any help would be appreciated.
The second point is a bit more sticky. It seems that MyApp has set mainform as its startup form, which seems to create a global instance of it. I've looked everywhere and there's no explicit initializations of mainform except through MyAppCom. This becomes a problem when I initialize mainform from MyAppCom and child forms are trying to reference the global MyApp.mainform. In this case, it is obviously not initialized (since I didn't create it from MyApp).
Is this something other people have done? I've searched for a couple days now with no luck but I don't imagine I'm one of few who've tried. A little background on the product - it was originally written in VB6 and now is updated to VB.NET with new projects in C#. The wrapper is also written in C#.
Here is the com wrapper (MyAppCom) (names have been changed to protect the not-so-innocent):
public interface IMainCom
{
void Init();
}
[ClassInterface(ClassInterfaceType.None)]
public class MainCom : IMainCom
{
private MDIMain mMDIMain = null;
public void Init()
{
OpenMain();
}
private void OpenMain()
{
mMDIMain = new MDIMain();
mMDIMain.Show();
}
}
Here also is the App.Designer for MyApp:
Namespace My
Partial Friend Class MyApplication
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Public Sub New()
MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
Me.IsSingleInstance = false
Me.EnableVisualStyles = false
Me.SaveMySettingsOnExit = true
Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses
End Sub
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Protected Overrides Sub OnCreateMainForm()
Me.MainForm = Global.MyApp.MDIMain
End Sub
End Class
End Namespace
I was given this snippet of C# that works perfectly in Visual Studio 2010:
using System;
using System.Web.UI.WebControls;
public partial class MasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void RequestLanguageChange_Click(object sender, EventArgs e)
{
LinkButton senderLink = (LinkButton)sender;
Response.Redirect(Request.RawUrl.ApplyCultureToUrl(senderLink.CommandArgument));
}
}
And every online converter (and SharpDevelop) translates it to this in VB:
Imports System
Imports System.Web.UI.WebControls
Public Partial Class MasterPage
Inherits System.Web.UI.MasterPage
Protected Sub Page_Load(sender As Object, e As EventArgs)
End Sub
Protected Sub RequestLanguageChange_Click(sender As Object, e As EventArgs)
Dim senderLink As LinkButton = DirectCast(sender, LinkButton)
Response.Redirect(Request.RawUrl.ApplyCultureToUrl(senderLink.CommandArgument))
End Sub
End Class
VS also is doing the same with this:
Public NotInheritable Class Localization
Private Sub New()
End Sub
<System.Runtime.CompilerServices.Extension()> _
Public Shared Function ApplyCultureToUrl(rawUrl As String, culture As String) As String
Dim modifiedUrl As String
Saying System.Runtime.CompilerServices.Extension can only be run in modules.
The Problem:
In Visual Studio 2010, Request.RawUrl.ApplyCultureToUrl is underlined in blue, and it doesn't offer a solution. It just says ApplyCultureToUrl is not a member of 'String'. This is the only thing stopping my solution from working!
I researched on MSDN, and it says that the error means it must be surrounded by a module, but not being a coder, I have no idea how to fix it. The snippet is to help my ?lang=en-GB querystring show up in my multilingual website. Any help would be sincerely appreciated!
Update: I have the ApplyCulturetoUrl thing working, just by clicking a lot of icons in Visual Studio, and it spit this out:
Partial Public Class MasterPage
Inherits System.Web.UI.MasterPage
Protected Sub Page_Load(sender As Object, e As EventArgs)
End Sub
Protected Sub RequestLanguageChange_Click(sender As Object, e As EventArgs)
Dim senderLink As LinkButton = DirectCast(sender, LinkButton)
Response.Redirect(ApplyCultureToUrl(Request.RawUrl, senderLink.CommandArgument))
End Sub
Private Sub body()
Throw New NotImplementedException
End Sub
Private Function ApplyCultureToUrl(p1 As String, p2 As String) As String
Throw New NotImplementedException
End Function
End Class
And that's giving me no errors, although I don't know if it's correct ... hehe .... Now, the only other part of the code that's giving me an error is in localization.vb, a class, and it's like this:
Public NotInheritable Class Localization
Private Sub New()
End Sub
<System.Runtime.CompilerServices.Extension()> _
Public Shared Function ApplyCultureToUrl(rawUrl As String, culture As String) As String
Dim modifiedUrl As String
And System.Runtime.CompilerServices.Extension() is underlined in squiggly blue and it says Extension methods can only be defined in modules. I'm using all of your suggestions! Thank you for sticking with it!
It looks like ApplyCultureToUrl is an extension method.
Solving this could be as easy as importing the namespace in which ApplyCultureToUrl is defined.
However it may be more complex than this:
In VB.Net extensions methods have to be in a module, this has to be public to reference the extension from other projects. To include them you just need to reference the containing assembly and import the right namespace.
The MSDN page for VB.Net Extension methods is here.
Put the cursor to the ApplyCultureToUrl keyword in C# file and hit F12 button. This method defined as an extension method somewhere.
I don't know if Visual Basic supports extension methods, if no, you can define it in VB locally:
Private Function ApplyCultureToUrl(RawUrl as String, Command as String) As String
// body
End Function
In this case you'll call it as follows:
Response.Redirect(ApplyCultureToUrl(Request.RawUrl, senderLink.CommandArgument))
I need to manipulate the VBA environment of an application from a C# addin so I can add modules, event handlers etc to documents that are created by the addin.
I've done it before in VB.Net but can't see how to get at the IDE object in C#. Am I just missing a reference or a Using directive? I can't see anything appropriate in the references.
In VB.Net I have a reference to Microsoft.VisualBasic and I have done this:
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Public Module VBA
Private m_VBEnv As VBIDE.VBE
Private m_dlg As AddInDialog
Private Structure EventHandler
Public objectName As String
Public eventName As String
Public action As String
End Structure
Private m_handlers As New Collection
Public Function InitVBA(ByVal app As PBObjLib.Application, ByVal dlg As AddInDialog, ByVal scrWidth As Integer, ByVal scrHeight As Integer) As Boolean
InitVBA = False
Try
m_dlg = dlg
m_VBEnv = DirectCast(app.VBE, VBIDE.VBE)
m_VBEnv.MainWindow.Height = 480
m_VBEnv.MainWindow.Width = 640
m_VBEnv.MainWindow.Left = (scrWidth - m_VBEnv.MainWindow.Width)
m_VBEnv.MainWindow.Top = ((scrHeight - m_VBEnv.MainWindow.Height) - 50)
m_VBEnv.MainWindow.WindowState = VBIDE.vbext_WindowState.vbext_ws_Minimize ' .vbext_ws_Normal
HideVBWindow()
InitVBA = True
Catch e As Exception
dlg.LogMessage(AddInDialog.LogLevel.Err, "Failed to initialise VBA: " & e.Message)
End Try
End Function
...
End Module
I have added a reference to Microsoft.VisualBasic to my C# but it does not recognise VBIDE.VBE.
Also, how would I do the DirectCast bit in C#. Is it just a simple cast?
Any suggestions?
The answer was to ensure that all references were .NET references. I had a COM one hiding in there. I removed the VB related references, reloaded the project, added the references (all .NET this time) and it all came to life.
I have an ASP.NET web site project where I am using both VB.Net and C# class files. I have included separate sub folders in the App_Code directory for classes of each language.
However, while I can successfully make use of a C# class in a VB class, I cannot do the opposite: use a a VB class in a C# class.
So, to illustrate, I might have two classes such as this:
Public Class VBTestClass
Public Sub New()
End Sub
Public Function HelloWorld(ByVal Name As String) As String
Return Name
End Function
End Class
public class CSTestClass
{
public CSTestClass()
{
}
public string HelloWorld(string Name)
{
return Name;
}
}
I can make use of the CS class in my VB class, with the "Imports" statement. So this works well:
Imports CSTestClass
Public Class VBTestClass
Public Sub New()
End Sub
Public Function HelloWorld(ByVal Name As String) As String
Return Name
End Function
Private Sub test()
Dim CS As New CSTestClass
CS.HelloWorld("MyName")
End Sub
End Class
But making use of the VB class in my C#, with the "using" statement, does not work:
using VBTestClass;
public class CSTestClass
{
public CSTestClass()
{
}
public string HelloWorld(string Name)
{
return Name;
}
}
I get an error that "the type or namespace "VBTestClass" could not be found". What am I missing here?
The best way to look at using/Imports as a shortcut to skip fully qualifying namespaces. The behaviour is the same across vb and c#.
Consider the examples:
fully qualyfying:
void DoSomething()
{
var p = new Interfaces.CPDATA.DataHolders.Placement();
}
skip the namespaces:
using Interfaces.CPDATA.DataHolders;
void DoSomething()
{
var p = new Placement();
var t = new Trade();
}
and a little shortcut trick
using data = Interfaces.CPDATA.DataHolders;
void DoSomething()
{
var p = new data.Placement();
var t = new data.Trade();
}
and a replacement trick:
using t = Interfaces.CPDATA.DataHolders.Placement;
void DoSomething()
{
var p = new t(); // happy debagging
}
As for code files in different languages in ASP.NET App_Code folder: DO NOT USE IT. For:
they won't work when using Web Application project
they will not compile when using csc or vbc compiler in continuous integration project outside of Visual Studio
and they will generally give you a lot of pain on infrastructure side of things.
Best way is to create separate Class Library projects for respective language and use them.
On top of it there are a lot of interesting things going on when running such project from under visual studio and iis. If you're curious you can take a look at various files sitting in
\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\{project name}\{tempname}
it should give you a good idea how asp.net engine combines the code files for aspx pages.
Aimed with that useless information we can now tell that having a CSTestClass class in the same namespace statement "Imports CSTestClass" is not really useful. Good coding style would be to have all of them wrapped in a namespaces statements MyWebProject.VbCode and MyWebProject.CsCode for example. Then statements "using MyWebProject.VbCode" and "Imports MyWebProject.CsCode" would make more sense to the compiler.
I think I found the problem and seems without a reflection you can't do it as a cross reference.
The reason is pretty simple, depends how the orders you define your codeSubDirectories, I think you made it this way:
<codeSubDirectories>
<add directoryName="CSCode"/>
<add directoryName="VBCode"/>
</codeSubDirectories>
As we know each directory will be build to different assembly, and they will be build one by one from top to bottom based on your settings.
So as you have CSCode folder defined first, it will be built first, and then compiler start to build VBCode, so using the CS class is OK as it can find the assembly to reference.
But if you do it reversely, as you mentioned to reference VB code in CS, it firstly build CSCode folder and at that time the assembly of VBCode does not exist so it throw exceptions.
So for make it work with CS using VB, just simply change the folder setting order:
<codeSubDirectories>
<add directoryName="VBCode"/>
<add directoryName="CSCode"/>
</codeSubDirectories>
But then you will lose the ability to use any CS class in VB as this time VBCode compile first.
So my suggestion is go with reflection to load it at run time so that compiler can let you go.
Hope my explanation is clear enough.
Thanks
the using statement is for namespaces not class names, put the VBClass inside a namespace and then, use the "using" statement:
Namespace MyFoo
Public Class VBTestClass
Public Sub New()
End Sub
Public Function HelloWorld(ByVal Name As String) As String
Return Name
End Function
End Class
End Namespace
now in c#:
using MyFoo;
...
THe difference is in how the Imports keyword works compared to the using keyword.
The using keyword can only be used to specify namespaces, while the Imports keyword can also be used to specify classes.
So, Imports CSTestClass specifies that classes, interfaces and enums inside that class should be available, but the class doesn't contain any of those, so the Imports statement is not needed.
When you try to use using VBTestClass it won't work, as VBTestClass is not a namespace.
So, just remove the Imports and using statements, and it should work fine. As the classes are in the same assembly, they already know about each other.