VS 2015 Get output location path from a usercontrol-VBForums
Results 1 to 29 of 29

Thread: Get output location path from a usercontrol

  1. #1

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Get output location path from a usercontrol

    Ok ... If I have a usercontrol that I am making, is there a way to get the current build output path from within the control, for the assembly that it is inserted onto?

    Hope that makes sense :P
    Thanks in advance,
    Kris Bennett

  2. #2
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,289

    Re: Get output location path from a usercontrol

    I think that information can only be present if debug information is generated for the assembly, which isn't done in a release build.

    What are you trying to accomplish? That information won't be relevant once the code is deployed.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  3. #3

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Basically I want to get the filename of the .exe ... or .dll for the thing that the control is inserted onto ...
    or be able to access its last built System.Reflection.Assembly...

    .. and, yes, I know that this would only be updated when the project is built ... but I am OK with that...

    I want to make a UI editor that shows a list of types that are accessible from the assembly

    Thanks,
    Kris

  4. #4
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    97,409

    Re: Get output location path from a usercontrol

    Assembly.GetEntryAssembly will generally give you an Assembly object for the EXE that was originally run. GetCallingAssembly would allow you to get an Assembly object representing the direct caller of certain code in your UC, so that would allow you to differentiate between the original EXE and a DLL that might use your UC.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    Here is example I to get a list of all the monsters defined in DemonArena:-
    vbnet Code:
    1. '  
    2.         Dim asm As Assembly = Assembly.GetExecutingAssembly()
    3.  
    4.         For Each t As Type In asm.GetTypes
    5.             If t.GetInterface("IDemon") IsNot Nothing AndAlso Not t.IsAbstract Then
    6.                 Dim mi As New ToolStripMenuItem
    7.  
    8.                 mi.Text = t.Name
    9.                 mi.Tag = t
    10.  
    11.                 AddHandler mi.Click, AddressOf EH_MenuItemClick
    12.                 MenuStrip1.Items.Add(mi)
    13.             End If
    14.         Next

    The above code looks for all non-abstract types in the executing assembly that implements the IDemon interface.

    Here's the code with only the bits relevant to your question:-
    vbnet Code:
    1. '
    2.         Dim asm As Assembly = Assembly.GetExecutingAssembly()
    3.  
    4.         For Each t As Type In asm.GetTypes
    5.          
    6.  
    7.         Next

    The above enumerates all types in the assembly. You can use the properties of type t to filter out the types you're not interested in.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  6. #6
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    Here's another example that enumerates all controls from every assembly that has been loaded.
    vbnet Code:
    1. '
    2.         'Enumerate all loaded assemblies
    3.         For Each a As Assembly In AppDomain.CurrentDomain.GetAssemblies()
    4.  
    5.             'Enumerate all types in the assembly
    6.             For Each t As Type In a.GetTypes.Where(Function(t1) t1.IsSubclassOf(GetType(Control)))
    7.                 Debug.WriteLine(t.Name)
    8.             Next
    9.  
    10.         Next

    Note that the above will enumerate ALL loaded assemblies, even the standard assemblies like System.Core, and not just the assemblies created by you in your solution.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  7. #7

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Quote Originally Posted by jmcilhinney View Post
    Assembly.GetEntryAssembly will generally give you an Assembly object for the EXE that was originally run. GetCallingAssembly would allow you to get an Assembly object representing the direct caller of certain code in your UC, so that would allow you to differentiate between the original EXE and a DLL that might use your UC.
    Thanks , but I already know this jmcilhinney and Niya ... I should of probably said I want this at design time though
    ... that method is not possible to get the assembly that the control is sitting on in design time.

    Any other ideas?
    Thanks,
    Kris

  8. #8
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    The designer runs the same code from the same assemblies so there shouldn't be a reason reflection doesn't work. In fact, a lot of designer functionality is dependent on reflection. You're probably doing something wrong.

    I still don't get what you're trying to do. Are you looking for the assembly where the Control is defined? Are you looking for the assembly where the Control is being used? Could you clarify?

    I suspect the problem is that you're simply looking in the wrong assemblies for whatever it is you want.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  9. #9
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    97,409

    Re: Get output location path from a usercontrol

    To clarify, you're saying that you want your compiled control to be able to determine, at design time, where the compiled EXE will be saved when it's used in a project, correct? I'm curious to know what use that would be.
    Last edited by jmcilhinney; Dec 15th, 2017 at 09:59 AM.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  10. #10

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Quote Originally Posted by jmcilhinney View Post
    To clarify, you're saying that you want your compiled control to be able to determine, at design time, where the compiled EXE will be saved when it's used in a project, correct? I'm curious to know what use that would be.
    What I want to achieve:
    Name:  screen.png
Views: 80
Size:  11.6 KB
    ...This should list the types available to the assembly, that the user control is inserted on ONLY

    Ok ... if I have the following project structure:

    Application - Project that opens form that is contained in FormHolder
    FormHolder - Holds a form that contains the usercontrol in ControlHolder (This assembly has a form that the user control is inserted onto)
    ControlHolder - Holds the usercontrol

    These are the results at runtime - bold is the one that I need:
    GetCallingAssembly: System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
    GetEntryAssembly: Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
    GetExecutingAssembly: ControlHolder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
    Parent?.GetType.Assembly: FormHolder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

    ... but I require this at design time ... at design time these are the results:

    GetCallingAssembly: System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
    GetEntryAssembly: Nothing
    GetExecutingAssembly: ControlHolder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
    Parent?.GetType.Assembly: System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

    As stated I am making a UIEditor for a usercontrol so that the user can select a Type... Property:

    VB.Net Code:
    1. <Editor(GetType(TypeTypeEditor), GetType(UITypeEditor))>
    2. Public Property DataType As Type

    UIEditor is filled with:
    VB.Net Code:
    1. Private Class ClassItem
    2.     Public ReadOnly Property ClassType As Type
    3.     Public Sub New(ClassType As Type)
    4.         Me.ClassType = ClassType
    5.     End Sub
    6.     Public Overrides Function ToString() As String
    7.         Return ClassType.FullName
    8.     End Function
    9. End Class

    From the following method:
    VB.Net Code:
    1. Dim AssembliesToSearch = {BaseAssembly}.Union(BaseAssembly.GetReferencedAssemblies.Select(Function(x) System.Reflection.Assembly.Load(x.FullName)))
    2. For Each a In AssembliesToSearch
    3.     For Each item In From xItem In a.GetTypes() Where xItem.IsAbstract = False AndAlso xItem.IsVisible = True
    4.         List.Add(New ClassItem(item))
    5.     Next
    6. Next
    7. lb.Items.AddRange(List.OrderBy(Function(x) x.ToString).ToArray)

    When the item is selected it selects the ClassItem.ClassType .. so the Type

    So I need BaseAssembly filled with the assembly that the control is inserted on ...
    Now I am sure that the assembly isn't necessary going to be built so will prob have to access it by filename (and only fill the list if it exists) to load the assembly from the designer... so will need the last built location.

    Thanks in advance,
    Kris

    EDIT:

    Also just noticed that even the executing assembly is not the one that was built when building the project ... but a temp one ... in my case in:
    %AppData%\..\Local\Microsoft\VisualStudio\14.0\ProjectAssemblies\tasg1zl001\ControlHolder.dll

    ... strange ... I mean you have to build your project to have controls show in designers ... why not just use their built location??!

  11. #11
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    What do you mean by "holds the control". Understanding what you mean by this is the key to everything.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  12. #12

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Quote Originally Posted by Niya View Post
    What do you mean by "holds the control". Understanding what you mean by this is the key to everything.
    The assembly that you insert the user control onto... controls parent assembly

    Kris

  13. #13
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    Quote Originally Posted by i00 View Post
    The assembly that you insert the user control onto... controls parent assembly

    Kris
    Err....I still don't know what you mean. How does one insert a control into an assembly?

    An assembly can either contain control types or they can have code that references control types either from themselves or other assemblies. Those are the only two relationships that are possible between objects and assemblies.

    Assemblies are just a collection of types and resources. Types are classes that can contain data and/or executable code. The classes can be controls, or any other type of object.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  14. #14
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,289

    Re: Get output location path from a usercontrol

    I feel like I typed a longish answer to this and now I don't see it, so now I'm worried that answer went to a different thread.

    The angle of the answer was "It might not be possible, but you need to use a debugger to find out. You have to use the debugger, because you're going to have to reverse-engineer some things that aren't documented, and I'm only comfortable talking about what is documented."
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  15. #15

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Quote Originally Posted by Niya View Post
    Err....I still don't know what you mean. How does one insert a control into an assembly?

    An assembly can either contain control types or they can have code that references control types either from themselves or other assemblies. Those are the only two relationships that are possible between objects and assemblies.

    Assemblies are just a collection of types and resources. Types are classes that can contain data and/or executable code. The classes can be controls, or any other type of object.
    The assembly for the controls parent...

    At runtime you can get this by going (within the control):
    Me.Parent.Assembly

    Thanks,
    Kris

  16. #16
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    Quote Originally Posted by i00 View Post
    The assembly for the controls parent...

    At runtime you can get this by going (within the control):
    Me.Parent.Assembly

    Thanks,
    Kris
    You mean like this:-
    vbnet Code:
    1. '
    2.     Private Function GetControlParentAssembly(ByVal c As Control) As Assembly
    3.  
    4.         If c.Parent IsNot Nothing Then
    5.             Return c.Parent.GetType.Assembly
    6.         End If
    7.         Return Nothing
    8.     End Function

    Or if you want to do it from within a Control:-
    vbnet Code:
    1. Imports System.Reflection
    2.  
    3. Public Class MyCustomControl
    4.     Inherits Control
    5.  
    6.  
    7.     Private Function GetParentAssembly() As Assembly
    8.         If Me.Parent IsNot Nothing Then
    9.             Return Me.Parent.GetType.Assembly
    10.         End If
    11.         Return Nothing
    12.     End Function
    13.  
    14. End Class
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  17. #17

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Quote Originally Posted by Niya View Post
    You mean like this:-
    Yes ... but, as mentioned, that method only works correctly at runtime .

    Kris

  18. #18
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,289

    Re: Get output location path from a usercontrol

    I'm not blowing smoke in #14.

    Sometimes the thing we want to do is not possible. Design-time is NOT run-time.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  19. #19
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    Quote Originally Posted by Sitten Spynne View Post
    I'm not blowing smoke in #14.

    Sometimes the thing we want to do is not possible. Design-time is NOT run-time.
    Actually you're wrong in this case. The designer works by executing code. Many things that are possible at runtime are also possible at design time.

    Quote Originally Posted by i00 View Post
    Yes ... but, as mentioned, that method only works correctly at runtime .

    Kris
    That's strange. I got it to work in the designer with no problems:-


    Here's the code for the control:-
    vbnet Code:
    1. Imports System.Reflection
    2.  
    3. Public Class MyCustomControl
    4.     Inherits Control
    5.  
    6.     Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
    7.         MyBase.OnPaint(e)
    8.  
    9.         Dim asm As Assembly = GetControlParentAssembly(Me)
    10.  
    11.         If asm IsNot Nothing Then
    12.             e.Graphics.DrawString(asm.FullName, Me.Font, Brushes.Black, New PointF(2, 2))
    13.         End If
    14.  
    15.         ControlPaint.DrawBorder(e.Graphics, Me.ClientRectangle, Color.Black, ButtonBorderStyle.Solid)
    16.     End Sub
    17.  
    18.     Private Function GetControlParentAssembly(ByVal c As Control) As Assembly
    19.  
    20.         If c.Parent IsNot Nothing Then
    21.             Return c.Parent.GetType.Assembly
    22.         End If
    23.         Return Nothing
    24.     End Function
    25.  
    26. End Class
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  20. #20

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Quote Originally Posted by Niya View Post
    Actually you're wrong in this case. The designer works by executing code. Many things that are possible at runtime are also possible at design time.

    That's strange. I got it to work in the designer with no problems:-

    Here's the code for the control:-
    I demonstrated that in #10 .. yes technically it works ... as in doesn't crash ... but an instance of Windows.Forms is used to parent (box) the control for the designer... at runtime this will be the assembly that the control is inserted onto not Windows.Forms ... that is not what I want as mentioned in #17.

    Kris

  21. #21
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    Quote Originally Posted by i00 View Post
    I demonstrated that in #10 .. yes technically it works ... as in doesn't crash ... but an instance of Windows.Forms is used to parent (box) the control for the designer... at runtime this will be the assembly that the control is inserted onto not Windows.Forms ... that is not what I want as mentioned in #17.

    Kris
    Well that certainly is weird. At this point you need to debug that code when it runs at design time. Single step through it and see what is actually happening line by line. That's what I do when I face problems like this. It sounds like you have a lot of complicated stuff going on in your classes. You may have made a mistake somewhere in your code that results in the different run time behavior.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  22. #22
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,289

    Re: Get output location path from a usercontrol

    It's not weird, it's just wrong to assume the designer works by running the .exe. I kind of did this as my job for a long time.

    The designer is a process that hosts the form. That means things like GetEntryAssembly() aren't going to return the same thing as they would at Runtime. Probably the most reliable thing here will be to look at a StackTrace from a breakpoint while in the designer and manually find the frame that represents the boundary. Once you see it a couple of times you get the hang of it, but it's a little different depending on exactly what's going on in your program.

    To get the right kind of breakpoint, you need 2 copies of Visual Studio open with your project. Use one to attach to the other Visual Studio. It got a little more complex at some point because they separated the designer into a different process. You might have to hunt that one down. When you get it set up right, you can debug your control in the designer. That's the perfect time to investigate the StackTrace.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  23. #23
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,289

    Re: Get output location path from a usercontrol

    Here's the kind of quick example you get if you spend half an hour in the debugger:

    I made a project that has a ClassLibrary1 that contains a custom control. There's a Windows Forms application that hosts the control. The control's constructor prints a stack trace and some information about the static assemblies you can reference easily. Here's what happens.

    Runtime
    Call stack:
    Code:
       at ClassLibrary1.Class1..ctor()
       at WindowsApp43.Form1.InitializeComponent()
       at WindowsApp43.Form1..ctor()
       at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
       at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
       at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
       at System.Activator.CreateInstance[T]()
       at WindowsApp43.My.MyProject.MyForms.Create__Instance__[T](T Instance)
       at WindowsApp43.My.MyProject.MyForms.get_Form1()
       at WindowsApp43.My.MyApplication.OnCreateMainForm()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at WindowsApp43.My.MyApplication.Main(String[] Args)
    Pretty sensible, Main creates the Application context, which starts creating the form, which has to create the control.

    Assemblies:

    The "entry" assembly is WindowsApp43, the .exe. The "executing" assembly is ClassLibrary1, the DLL.

    Design-time
    Call stack:
    Code:
       at ClassLibrary1.Class1..ctor()
       at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.SecurityUtils.SecureConstructorInvoke(Type type, Type[] argTypes, Object[] args, Boolean allowNonPublic, BindingFlags extraFlags)
       at System.ComponentModel.ReflectTypeDescriptionProvider.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at Microsoft.VisualStudio.Design.MultiTargetingProvider.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.TypeDescriptionProvider.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.DelegatingTypeDescriptionProvider.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.DelegatingTypeDescriptionProvider.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.TypeDescriptor.CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, Object[] args)
       at System.ComponentModel.Design.DesignSurface.CreateInstance(Type type)
       at Microsoft.VisualStudio.Design.VSDesignSurface.CreateInstance(Type type)
       at System.ComponentModel.Design.DesignerHost.System.ComponentModel.Design.IDesignerHost.CreateComponent(Type componentType, String name)
       at System.ComponentModel.Design.Serialization.DesignerSerializationManager.CreateInstance(Type type, ICollection arguments, String name, Boolean addToContainer)
       at System.ComponentModel.Design.Serialization.DesignerSerializationManager.System.ComponentModel.Design.Serialization.IDesignerSerializationManager.CreateInstance(Type type, ICollection arguments, String name, Boolean addToContainer)
       at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeInstance(IDesignerSerializationManager manager, Type type, Object[] parameters, String name, Boolean addToContainer)
       at System.ComponentModel.Design.Serialization.ComponentCodeDomSerializer.DeserializeInstance(IDesignerSerializationManager manager, Type type, Object[] parameters, String name, Boolean addToContainer)
       at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager, String name, CodeExpression expression)
       at System.ComponentModel.Design.Serialization.CodeDomSerializer.DeserializeStatementToInstance(IDesignerSerializationManager manager, CodeStatement statement)
       at System.ComponentModel.Design.Serialization.CodeDomSerializer.Deserialize(IDesignerSerializationManager manager, Object codeObject)
       at System.Windows.Forms.Design.ControlCodeDomSerializer.Deserialize(IDesignerSerializationManager manager, Object codeObject)
       at System.ComponentModel.Design.Serialization.TypeCodeDomSerializer.DeserializeName(IDesignerSerializationManager manager, String name, CodeStatementCollection statements)
       at System.ComponentModel.Design.Serialization.TypeCodeDomSerializer.Deserialize(IDesignerSerializationManager manager, CodeTypeDeclaration declaration)
       at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
       at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
       at System.ComponentModel.Design.Serialization.BasicDesignerLoader.BeginLoad(IDesignerLoaderHost host)
       at System.ComponentModel.Design.DesignerHost.BeginLoad(DesignerLoader loader)
       at System.ComponentModel.Design.DesignSurface.BeginLoad(DesignerLoader loader)
       at Microsoft.VisualStudio.Design.DesignerService.Microsoft.VisualStudio.Designer.Interfaces.IVSMDDesignerService.CreateDesigner(Object provider, Object designerLoader)
       at Microsoft.VisualStudio.LanguageServices.Implementation.AbstractEditorFactory.CreateEditorInstance(UInt32 grfCreateDoc, String pszMkDocument, String pszPhysicalView, IVsHierarchy vsHierarchy, UInt32 itemid, IntPtr punkDocDataExisting, IntPtr& ppunkDocView, IntPtr& ppunkDocData, String& pbstrEditorCaption, Guid& pguidCmdUI, Int32& pgrfCDW)
       at Microsoft.VisualStudio.Shell.Interop.IVsUIHierarchy.ExecCommand(UInt32 itemid, Guid& pguidCmdGroup, UInt32 nCmdID, UInt32 nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
       at Microsoft.Internal.VisualStudio.PlatformUI.HierarchyUtilities.<>c__DisplayClass35_0.<ExecHierParentChain>b__1()
       at Microsoft.VisualStudio.ErrorHandler.CallWithCOMConvention(Func`1 method, Boolean reportError, Boolean setShellErrorInfo)
       at Microsoft.Internal.VisualStudio.PlatformUI.HierarchyUtilities.ExecHierParentChain(IVsHierarchyItemManager manager, IVsUIHierarchy lpUIHCmd, IVsUIHierarchy lpUIHCurrent, UInt32 itemidCurrent, Guid& pguidCmdGroupRef, UInt32 nCmdID, UInt32 nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
       at Microsoft.VisualStudio.PlatformUI.HierarchyItem.HierarchyInvocationController.Invoke(IEnumerable`1 items, InputSource inputSource, Boolean preview)
       at Microsoft.Internal.VisualStudio.PlatformUI.InvocationController.Invoke(IEnumerable`1 items, InputSource inputSource, Boolean preview, Func`2 getController)
       at Microsoft.Internal.VisualStudio.PlatformUI.InvocationController.Invoke(IEnumerable`1 items, InputSource inputSource, Boolean preview)
       at Microsoft.Internal.VisualStudio.PlatformUI.PivotTreeViewItem.InvokeItem(InputDevice sourceDevice)
       at Microsoft.Internal.VisualStudio.PlatformUI.PivotTreeViewItem.OnMouseLeftButtonDown(MouseButtonEventArgs e)
       at System.Windows.UIElement.OnMouseLeftButtonDownThunk(Object sender, MouseButtonEventArgs e)
       at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
       at System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e)
       at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
       at System.Windows.Input.InputManager.ProcessStagingArea()
       at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
       at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
       at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
       at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
    You might notice this is a little different. I can see from this call stack a ton of WPF frames that are devenv.exe itself, and by the time we get to the layers with TypeDescriptor we're in WinForms Designer land. You know what I don't see in this call stack? Anything related to WindowsApp43, the .exe file. Interesting.

    The Entry assembly is Nothing. Visual Studio is apparently either not directly a .NET application or something else fishy. The Executing assembly is ClassLibrary1, the DLL.

    Conclusion
    Runtime is not design-time. "Common sense" doesn't apply.

    I vaguely remember knowing that the Form you see on the designer isn't even a real form, it's all some kind of pseudo-form that just happens to have the same properties as a form. I didn't feel like digging in the debugger to verify that, it's only about 10 minutes more work but I got the payload I wanted.

    If you have the ExecutingAssembly for the control, you can use the CodeBase property to get an idea of the path. But in my test project that's not useful, because the control is in a class library that isn't the same assembly as the executable, which means it's in a different location. I double-checked. It's in that AppData directory as indicated, and ONLY the DLL is there. That's because the designer doesn't rely on "all the DLLs are in the same directory", it manually loads what it needs.

    So I don't have conclusive information that makes me believe you can get from the control's assembly to the executable's assembly. And I have reason to believe even if you could get the exectuable's assembly, its location at design-time does not simulate the run-time deployment environment.

    MAYBE there's some way to get from a custom designer into the VS automation system. From there you could probably suss out a lot more. That would be an awful lot to go over and it'd take me days to get that headspace back.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  24. #24
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    I wish this question had come up when I was deep in development of custom controls. I came across problems like this all the time and was able to solve most of them. I would have probably been able to figure this out too. As of now, I haven't done anything serious with regards to control development in a couple years. However, custom controls was always my kinda thing, even from VB6. I always loved doing them and although I'm contemplating leaving WinForms behind one day, it's likely I'll dive back into control development sometime before that.

    Being so long from it, my memory of really deep technical specifics has faded somewhat but something in me believes what i00 wants is possible. Based on my own experience solving tricky problems like this, I would say he might need to shuffle around some stuff in his code. I had to do a lot of refactoring myself in order to "trick" things into working but this is very grueling nearly every time. It involved a lot of trial and error and a lot of late nights hunting down obscure documentation.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  25. #25
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,289

    Re: Get output location path from a usercontrol

    Yeah I hear you, the design-time side of things was always kind of shaky in WinForms because it had "hundreds" of interested people instead of "millions" like run-time documentation. Part of the reason I only put a debugger to it today is because when you told me I was wrong in #14, my memory's just foggy enough I assumed you'd done the debugger work and I was wrong. Turns out we're both wandering around in a kind of fog!

    The worst was WPF design time. You can't even turn that stuff up via Google search anymore. I could only get to it via a link I bookmarked. That's a whole different story, though.

    Heck, I got surprised in this project because I thought I'd use the DesignMode property to make some code only run in design time. For some reason, that property's False when my code runs. This is EXACTLY how I remember working in the designer felt all the time.

    I really don't know how to proceed because the next steps are crazy things that would take quite a bit of research for me to even start prototyping. Usually a rule of thumb I had for accepting/rejecting a feature was to hunt around and see if someone big like Telerik had a similar feature at design-time. If I thought it was impossible, and no one else had a feature like it, I had a strong case for rejection. Every now and then they had it, and it meant I had to figure out what the heck they did. Sometimes that involved ILDASM. Usually that revealed a trick I'd have never figured out on my own, and that they probably found by accident.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  26. #26
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    Quote Originally Posted by Sitten Spynne View Post
    Part of the reason I only put a debugger to it today is because when you told me I was wrong in #14, my memory's just foggy enough I assumed you'd done the debugger work and I was wrong.
    I also did this kinda thing a lot in VB6. One of the biggest shocks I got when I started doing custom controls in .Net was how much different the design time environment was. The degree of influence you had over the design time environment was simply astonishing. What I found particularly interesting was how this influence was expressed. You simply wrote code. All the Visual Studio designers were just classes, no different on any technical level to any of the classes you would use or write for your run time functionality. This is why I said that run time and design time weren't that different. I was actually making a comparison to my experience in VB6 where run time behavior and design time behavior were truly different.

    VB6 designers were just this huge black box. As far as I could tell their inner workings were fundamentally different from the run time environment. I could be wrong, but it certainly felt that way. You could access it's functionality through some end points like PropertyBags and what not but the designer wasn't exposed in terms of normal program elements like classes and interfaces the way .Net designers were.

    To put it simply, .Net designers are normal .Net classes that help you build other .Net classes. VB6 designers are programs that help you build something resembling classes inside which you would place your executable code. In hindsight, it is quite weird.

    From a completely objective point of view, you are correct. Design time and run time are two different things but I was being very subjective. My apologies. I should have been clearer in expressing my thoughts.
    Last edited by Niya; Dec 19th, 2017 at 09:52 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  27. #27

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Quote Originally Posted by Sitten Spynne View Post
    in #14, my memory's just foggy enough I assumed you'd done the debugger work and I was wrong. Turns out we're both wandering around in a kind of fog!
    Wow ... well until now I didn't even know you can debug the designer stuff thanks for that ... kudos given ... will save me A LOT of time

  28. #28

    Thread Starter
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,214

    Re: Get output location path from a usercontrol

    Quote Originally Posted by Sitten Spynne View Post
    Usually a rule of thumb I had for accepting/rejecting a feature was to hunt around and see if someone big like Telerik had a similar feature at design-time. If I thought it was impossible, and no one else had a feature like it, I had a strong case for rejection.
    I think something like this should be possible ...

    The UITypeEditor on the BindingSource.Datasource property seems to do some reflection stuff based on the reference tree from the assembly that the UC is on when you select Object in it

    Kris

  29. #29
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    5,580

    Re: Get output location path from a usercontrol

    Quote Originally Posted by i00 View Post
    Wow ... well until now I didn't even know you can debug the designer stuff thanks for that ... kudos given ... will save me A LOT of time
    Well that's what I meant when I said this:-
    Quote Originally Posted by Niya View Post
    Well that certainly is weird. At this point you need to debug that code when it runs at design time.
    I assumed you knew what I was talking about. My bad.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.