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.
Related
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
I've struggle several hours on that and I can't find what I'm doing wrong.
I created a new C# dll project, here is the content of the only class it contain:
using System;
using System.Runtime.InteropServices;
namespace PolygonSl {
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Config {
[ComVisible(true)]
public string GetCompany() {
return "POL";
}
}
}
I basically remove everything from it trying to make it work, the only reference is System.
I checked the Make assembly COM-Visible flag on the Assembly Information and my project is signed (seams required for codebase).
It compiling fine, after that, I called RegAsm.exe, giving it my dll, I added /codebase and /tlb, the command is successful.
When I go to my VBA project, I can add my new tlb file to the references, working fine. After, I can use it in my code, the autocomplete is working and I can compile with no errors.
Then, when I execute, I got this:
Run-time error '430':
Class does not support Automation or does not support expected interface
Here is my code sample in the VBA:
Private Sub Button1_Click()
'With CreateObject("PolygonSl.Config")
With New PolygonSl.Config
MessBox .GetCompany, MB_OK, "Test"
End With
End Sub
I tried late binding and my code is running fine with it but I'd like to be able to use the autocomplete.
Anyone have a suggestion on what I could try to make it work?
Edit (Adding some details on my environment)
I work on VS2008 for projects related to Dynamics SL (one of the Microsoft ERPs)
I'm on Windows Server 2008 R8 Standard, running from VMWare
Compiling on Framework 3.5, Release, x86, Dynamics SL client is 32 bits
I tried my dll on Dynamics but also on Excel to be sure that the problem was not Dynamics ;)
I think you need to define an interface to be able to see getcompany.
using System;
using System.Runtime.InteropServices;
namespace PolygonSl
{
[Guid("6DC1808F-81BA-4DE0-9F7C-42EA11621B7E")]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IConfig
{
string GetCompany();
}
[Guid("434C844C-9FA2-4EC6-AB75-45D3013D75BE")]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ClassInterface(ClassInterfaceType.None)]
public class Config : IConfig
{
public string GetCompany()
{
return "POL";
}
}
}
You can generate the interface automatically by placing the cursor in the class definition and using Edit.Refactor.ExtractInterface.
I'd have to admit that I'm at the absolute edge of my abilities here and the above is put together based on examples I've seen elsewhere.
Edit
The following test code works fine on my PC
Option Explicit
Sub polygontest()
Dim my_polygon As SOPolygon.Config
Set my_polygon = New SOPolygon.Config
Debug.Print my_polygon.GetCompany
End Sub
Where SOPolygon is the project name.
I am a newbie of C# and MS visual studio, and I want to use the C# class which defined in another file, but can't get it work.
Here is the program.cs(and why can't I rename that file ?)
using System;
namespace TestCSharp2
{
class Program
{
static void Main(string[] args)
{
Class2 class2 = new Class2();
// here the IDE will complain that cant find namespace or balabala..
class2.setValue(10);
Console.WriteLine(class2.getValue().ToString());
Console.ReadKey();
}
}
}
And here is the Class2 that I want to use in file Class2.cs:
namespace TestCSharp2
{
class Class2
{
int i;
public void setValue(int i)
{
this.i = i;
}
public int getValue()
{
return this.i;
}
}
}
Should I #include or something? isn't use namespace enough?
As some guys asked if they are in the same assembly/same project, I presume they were, because here is the procedure how they are created:
A new project using the template of Console C# Project, then the program.cs was created by default.
The Class2.cs was created with [File] -> [New] -> [File] -> [C# class] and saved in the same folder where program.cs lives.
To be honest, I don't know if they are in same assembly / same project, but I guess they were.
According to your explanation you haven't included your Class2.cs in your project. You have just created the required Class file but haven't included that in the project.
The Class2.cs was created with [File] -> [New] -> [File] -> [C# class] and saved in the same folder where program.cs lives.
Do the following to overcome this,
Simply Right click on your project then -> [Add] - > [Existing Item...] : Select Class2.cs and press OK
Problem should be solved now.
Furthermore, when adding new classes use this procedure,
Right click on project -> [Add] -> Select Required Item (ex - A class, Form etc.)
Yeah, I just made the same 'noob' error and found this thread.
I had in fact added the class to the solution and not to the project.
So it looked like this:
Just adding this in the hope to be of help to someone.
It would be more beneficial for us if we could see the actual project structure, as the classes alone do not say that much.
Assuming that both .cs files are in the same project (if they are in different projects inside the same solution, you'd have to add a reference to the project containing Class2.cs), you can click on the Class2 occurrence in your code that is underlined in red and press CTRL + . (period) or click on the blue bar that should be there. The first option appearing will then add the appropriate using statement automatically. If there is no such menu, it may indicate that there is something wrong with the project structure or a reference missing.
You could try making Class2 public, but it sounds like this can't be a problem here, since by default what you did is internal class Class2 and thus Class2 should be accessible if both are living in the same project/assembly. If you are referencing a different assembly or project wherein Class2 is contained, you have to make it public in order to access it, as internal classes can't be accessed from outside their assembly.
As for renaming: You can click Program.cs in the Solution Explorer and press F2 to rename it. It will then open up a dialog window asking you if the class Program itself and all references thereof should be renamed as well, which is usually what you want. Or you could just rename the class Program in the declaration and again open up the menu with the small blue bar (or, again, CTRL+.) and do the same, but it won't automatically rename the actual file accordingly.
Edit after your question edit: I have never used this option you used, but from quick checking I think that it's really not inside the same project then. Do the following when adding new classes to a project: In the Solution Explorer, right click the project you created and select [Add] -> [Class] or [Add] -> [New Item...] and then select 'Class'. This will automatically make the new class part of the project and thus the assembly (the assembly is basically the 'end product' after building the project). For me, there is also the shortcut Alt+Shift+C working to create a new class.
namespace TestCSharp2
{
**public** class Class2
{
int i;
public void setValue(int i)
{
this.i = i;
}
public int getValue()
{
return this.i;
}
}
}
Add the 'Public' declaration before 'class Class2'.
According to your example here it seems that they both reside in the same namespace. I conclude that they are both part of the same project (if you haven't created another project with the same namespace)
and all classes by default are defined as internal to the project they are defined in, if haven't declared otherwise, therefore I guess the problem is that your file is not included in your project.
You can include it by right clicking the file in the solution explorer window => Include in project, if you cannot see the file inside the project files in the solution explorer then click the show the upper menu button of the solution explorer called show all files (just hover your mouse cursor over the button there and you'll see the names of the buttons).
Just for basic knowledge:
If the file resides in a different project\ assembly then it has to be defined,
otherwise it has to be defined at least as internal or public.
In case your class is inheriting from that class that it can be protected as well.
I was having the same problem here. Found out that the problem was with an Advanced Property of the file. There is there an option with the name 'Compilation Action' (may be not with the exact words, I am translating - my VS is in Portuguese).
My Class1.cs file was there as "Content" and I just had to change it to "Compile" to make it work, and have the classes recognized by the others files in the same project.
Just make two projects in two different files then rename the "Program.cs" of one of the two files
and copy it then paste it next to the Program.cs of the other file and that's it.
In your project there will be a file with .csproj extension.
Double click on it to open the project in the Visual Studio. Otherwise, if you make a new class, it won't link with other classes.
When u diclare your , var
you , can use private , declarasion
using System;
private Class class;
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 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.