I am working in a solution which contains multiple projects. I need to access a method from one project in a different project. We have a separate project for handling incoming packets and updating the local data and then from this i need to access a method in the main application project (which displays a custom notification to the user)
In the main application i have a method with the following signature
Public Sub NotifyRemoved(ByVal message As String)
In the packet handling project i have tried using an invoke to call the method like so:
removedItems is a list of strings.
"MainForm" is the class the above method is within.
For Each removed As String In removedItems
Dim newType As Type = Type.GetType("MainForm")
Dim newConstructor As ConstructorInfo = newType.GetConstructor(Type.EmptyTypes)
Dim newClassObject As Object = newConstructor.Invoke(New Object() {})
Dim newMethod As MethodInfo = newType.GetMethod("NotifyRemoved")
newMethod.Invoke(newClassObject, New Object() {removed & " has been removed from list"})
Next
When i run this through debug the Type.GetType() method returns nothing and therefor throws an exception on the next line... I have tried some other ways using events etc. but all the method i can find seem to need direct access between the two classes.
any ideas?
Thanks in advance.
Add a Reference to the project with the .dll from the other project.
Project | Add reference | Browse (to find .dll )
Once it has been added you can then reference the Projects Routine by Project.Class.Routine
Related
As I am trying to figure out how to work with the Siemens Tia Portal Openness framework, I try to find an item in my Tia Portal project with the ControllerTarget type.
I try to find the items like this:
Imports Siemens.Engineering
Imports Siemens.Engineering.HW
Module Module1
Sub Main()
Dim myTiaPortal
myTiaPortal = New TiaPortal(TiaPortalMode.WithoutUserInterface)
'The portal is open, now create a project.
Dim tiaProject As Project
'Open the sample project:
Dim fileName As String
fileName = "C:\Path\To\Project\Sample_Project.ap13"
tiaProject = myTiaPortal.Projects.Open(fileName)
'Get the frist device from the project:
Dim tiaDevice As Device
tiaDevice = tiaProject.Devices.First
For Each item As IDeviceItem In tiaDevice.DeviceItems
Console.WriteLine(item.GetType())
Next
Console.ReadKey()
End Sub
End Module
This shows two items in the project:
Siemens.Engineering.HW.DeviceItemImplementation
Siemens.Engineering.HW.ControllerTargetImplementation
When I try to define an object of the type ControllerTargetImplementation I get the message that this datatype does not exist.
When I try to convert the item of type ControllerTargetImplementation to an object of type ControllerTarget, this seems to work perfectly.
Does this mean that the type returned by GetType() does not have to be the same as the actual type of the object? Is this normal? Or is this a strange thing in the openness platform?
When I try to define an object of the type ControllerTargetImplementation I get the message that this datatype does not exist.
Types can be internal to an assembly, which means that while they exist and things like GetType will show them to be there, you can't use them directly.
When I try to convert the item of type ControllerTargetImplementation to an object of type ControllerTarget, this seems to work perfectly.
Given the names involved here, it certainly sounds like ControllerTarget is the type being exposed to you, the consumer of the library, while the implementation of that type, perhaps a subclass or an implementation of an interface (ie is ControllerTarget a class or interface?) is hidden from you as you don't need to know about how it does it's job, nor interfere with it.
Does this mean that the type returned by GetType() does not have to be the same as the actual type of the object?
The actual type of the object is what is reported by GetType, but that doesn't mean that it's necessarily what you refer to it as. For instance, consider the following:
Class A
End Class
Class B
Inherits A
End Class
Sub Main
Dim obj as A = new B()
Console.WriteLine(obj.GetType())
End Sub
This will report obj as having a type of B (because that's the actual type we instantiated with new B()), even though it's stored against a variable of type A.
When reading an old project of mine I found something suspicious where I don't really understand why this part is working:
Public Shared Sub getXMLforProject(QueryString As String)
Dim linkStart As String = "http://example.org"
Dim linkEnd As String = "&tempMax=2000"
Dim target As String = linkStart & QueryString & linkEnd
'replaces parts that need encoding,
'groups(1) is the sign e.g. <= and groups(2) is the text that needs encoding
'groups(0) is the text of the full match (sign and encoding text)
target = rx.Replace(target, Function(m As Match) encodeURLString(m.Groups(1).Value) + encodeURLString(m.Groups(2).Value))
GUI.WebBrowser.Navigate(target)
Return True
End Sub
the respective path that seams suspicious to me is the line
GUI.WebBrowser.Navigate(target)
There is a class called GUI that realises the user interface, but in the file context there is no objects named "GUI" available, so the access must be done by using the class. How is it possible for this to work? Is there an implicit mechanism that redirects the call from the GUI-class to the GUI-object?
You are using VB.NET, it emulates the behavior of the Form class from earlier Visual Basic editions where using the type name was a legal way to refer to an instance of the class. Kinda necessary to give programmers a fighting chance to convert their VB6 projects. Underlying plumbing is the My.Forms object.
So, 99.9% odds are that the GUI class derives from System.Windows.Forms.Form. Especially given that it has a WebBrowser member. The Form is the host window for the browser.
let's say i have :
1) 1 WindowsForm on "A" Project
2) 1 WindowsForm on "B" Project
3) 1 class library (GAC)
Condition
Both of Project references is same
Part 1 :
I have my.settings in my class library to save configuration with public function
Part 2 :
I create value/configuration from "A" and store it in my class library.
settings has been successfully saved, and load the value/configuration with no errors
Question :
1). Why i can't load the value/configuration from "B" ? NullException shown
First I think, to use my.resources in class library but, my.resources is readonly
2). What best solution to connecting 1 class library to multiple project
code in class library to save value
Public Sub Kucing_simpan(ByVal value As String)
My.Settings.Kucing = value
My.Settings.Save()
End Sub
code in class library to load value
Public Function kucing_ambil()
Dim value As String
value = My.Settings.Kucing
Return value
End Function
code in "A"
dim save as new Zombie.Kencing 'My class Library Name
save.Kucing_simpan(textbox1.text)
code in "B"
dim load as new Zombie.Kencing 'My class Library Name
DataGridView1.Rows(0).Cells(1).Value = load.kucing_ambil
You cant do what you are trying to do - at least not the way you are going about it.
First, you have to understand how/where Settings are saved. With default naming of the app and such, project A - WindowsApplication1 will save its settings to something cryptic such as:
C:\Users\<UserName>\AppData\Local\Microsoft\_
WindowsApplication1_Url_ggn13vigzyicmtfkwaa3vi5tyxn0sy3r\1.0.0.0\user.config
NET creates the hash to make sure that apps with the same name have a different safe location to store settings. So, WindowsApplication3 will have a different hash; this is also how your 17th project with the name WindowsApplication1 doesnt accidentally load or find the settings of WinApp 1-16.
Next, your Settings Class Lib is not a separate application. As a DLL, it is operating as if it was a set of functions and such associated with the App calling it. So when Project A saves settings thru the ClassLib, they are saved to a different location than Project B. Even using a Class Lib, NET uses Application credentials and info to concoct the filename and path.
What you can do is write a Class which defines all the possible settings (or creates a List or Dictionary of them) then save to a fixed, known location such as:
Private Comp As String = "ZiggySoft"
Private Prod As String = "ZiggyWare"
Private settingsFile As String
'...
settingsfile = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
settingsfile = Path.Combine(settingsfile, Comp, Prod, "usersettings.dat")
This will result in:
"C:\Users\\AppData\Roaming\ZiggySoft\ZiggyWare\usersettings.dat"
Include the same file in each project (Add Existing Item, maybe pick Add As Link from the dropdown). Now, you can read and write your Settings to a file you are in charge of. You can save/load the entire class or List in 3-5 lines of code if you serialize it.
When Project A loads the settings, it would also get those which only apply to B or J or V, but common ones would and could be shared.
Hi all
I have handle of a usercontrol on external application in vb.net.
I know class type of that user control.
I want to get refrence to that object to check some properties of that object.
Is it possible and how?
thanks
I hope I do understand your question right...
You may try to insert a reference to your library (I assume your userControl is in this library). As a prerequisite this external application must be written in .Net or have some kind auf COM interface!
Then you may try to access the userControl class by
NAMESPACE.CLASS myReference = new NAMESPACE.CLASS();
hth
You can get some info by using interop, with some functions like GetWindowText and SendMessage, however this won't allow you to get all properties, and won't work on every type of application (WPF or Java come to mind).
The Control Class has a method FromHandle:
Dim myCtrl As knownType = Control.FromHandle(knownHandle)
'then get the known property using Reflection
Dim oProp As System.Reflection.PropertyInfo = myCtrl.GetType.GetProperty("KnownProperty")
Dim oValue As Object = oProp.GetValue(myCtrl, Nothing)
'or directly:
Dim oValueD as Object = myCtrl.knownProperty
I don't know if it works between processes.
You can change the connection string at run-time like this. You make the connection string setting available for writing as a separate property inside the MySettings class:
Partial Friend NotInheritable Class MySettings
Public WriteOnly Property RunTimeConnectionString()
Set(ByVal value)
My.Settings("MyConnectionString") = value
End Set
End Property
End Class
Then, in some place when the application is being initialized (before using any table adapters of typed datasets), write something like:
My.Settings.RunTimeConnectionString = My.Settings.ProductionConnectionString
Where ProductionConnectionString is a simple String setting. It is a User Scope setting so every user can change it (by assigning a value to it, similar to the code above) and save it by calling My.Settings.Save()
This code works well for connection strings which were initially created in the main project and stored in it's settings (= app.config file).
The connection string in the app.config actually has a longer name: MyApp.MySettings.MyConnectionString.
When you have a connection string stored in the app.config in a class library project, and reference that project in the main project, the app.config files will somehow be merged, so the class library has it's settings.
The thing that don't know how to do, is change a setting from the class library at run-time. I could copy the connection string setting from the class library to the main project's app.config. I must keep the same name, which looks something like: MyClassLibrary.My.MySettings.MyConnectionString.
Can the same principle I showed above be somehow applied to this second connection string?
I tested a little more, and found out that the same solution can be used inside a class library.
I made a new class (in the class library) with a shared (static) method like this:
Public Class MySettingsChanger
Public Shared Sub SetConnectionString(ByVal cnnString As String)
My.Settings.RunTimeConnectionString = cnnString
End Sub
End Class
And extended the MySettings class (in the class library) the same way as in the main project:
Namespace My
Partial Friend NotInheritable Class MySettings
Public WriteOnly Property RunTimeConnectionString()
Set(ByVal value)
My.Settings("MyConnectionString") = value
End Set
End Property
End Class
End Namespace
At least it works in my case. The name of the connection in the main project and in the class library is the same only (the short name, not the whole ProjectNamespace.MySettings.ConnectionName). I haven't tested with having a different name of the connection in the class library, but think it should not matter.
I searched more, and found a way, but it isn't really runtime. At least not as runtime as I would like it to be. Anyway, here is the code, I tested it and it worked, but required me to restart the application first. That's not very runtime to me.
Dim configLocation As String = Reflection.Assembly.GetExecutingAssembly().Location
Dim config As Configuration.Configuration = Configuration.ConfigurationManager.OpenExeConfiguration(configLocation)
config.ConnectionStrings.ConnectionStrings.Clear()
For i As Integer = 0 To Configuration.ConfigurationManager.ConnectionStrings.Count - 1
Dim connection As New Configuration.ConnectionStringSettings(Configuration.ConfigurationManager.ConnectionStrings(i).Name, My.Settings.ProductionConnectionString)
connection.ProviderName = Configuration.ConfigurationManager.ConnectionStrings(i).ProviderName
config.ConnectionStrings.ConnectionStrings.Add(connection)
Next
config.Save()
This is the article where I found this code.
Thanks for the message on the blog. Yes, it is hardly run-time as it requires you to stop running for the changes to be picked up. Unfortunately, because settings are loaded once and only once (when the app domain is loaded), there isn't a way for the settings infrastructure to pick up changes while running.
The only option is to either restart the app or recyle the app pool if a web application. Beyond that, you would have to roll your own.
I did the best I could :-)