I'm creating a program that has a "rehost workflowdesigner" (like Autodesk SubAssembly Composer did) and it fails to create the toolbox controls.
The error that occurs: System.IO.FileNotFoundException: Could not load file or assembly....
So far I understand that, because the DLL is not in the GAC, windows cannot find it.
So I tested the following hypotheses:
NETLOAD for the first time, without setting DLL folder in "support file search path" when calling the command, result: ERROR
Add the DLL folder to the "support file search path" and then NETLOAD when calling the command, result: WORKS
Enable autoload by the "LOADCTRLS" key (defined in IExtensionApplication.Initialize), without adding the DLL in the "support file search path" when calling the command, result: ERROR
Now that the dll is loaded by the registry ("LOADCTRLS" ), still without the "support file search path" when calling the command, result: ERROR
In the same cad session as in step 4, add the DLL to the ""support file search path", editing the field without clicking the "Browse" button when calling the command, result: ERROR
In the same cad session as in step 5, add the DLL to the ""support file search path", editing the field by clicking the "Browse" button when calling the command, result: ERROR
In the same cad session as in step 6, I call the NETLOAD command (filedia=1), navigate to the DLL folder, DO NOT SELECT ANYTHING AND CLICK CANCEL when calling the command, result: WORKS
I close cad, open it again, set FILEDIA=0 when calling the command, result: ERROR
In the same cad session of step 8, NETLOAD, I inform the full path of the DLL when calling the command, result: ERROR
In the same cad session as in step 9, FILEDIA=1, NETLOAD, I navigate to the folder, but I don't select anything, as in step 7, when calling the command, result: WORKS
So it concludes that the NETLOAD command doesn't just do an "Assembly.LoadFrom".
And the fact that it works with FILEDIA=1, makes me believe that it is the part of the code that shows the NETLOAD window that somehow makes the DLL, or its types visible and the System.IO.FileNotFoundException error does not occur
I added the code so you can look. If you can help me, thank you
"MyCustomActivity.vb"
Imports System.Activities
Imports System.Activities.Presentation
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Media.Imaging
<ToolboxBitmap(GetType(MyCustomActivity), "arc.png"), Designer(GetType(MyCustomDesigner))>
Public Class MyCustomActivity
Inherits CodeActivity
Protected Overrides Sub Execute(context As CodeActivityContext)
'faz alguma coisa
End Sub
End Class
Public NotInheritable Class MyCustomDesigner
Inherits MyActivityDesigner
Public Sub New()
MyBase.New(GetType(MyCustomActivity))
End Sub
End Class
Public MustInherit Class MyActivityDesigner
Inherits ActivityDesigner
Public Sub New(customActivityType As Type)
Dim toolAttrib As ToolboxBitmapAttribute = customActivityType.GetCustomAttributes(GetType(ToolboxBitmapAttribute), True)(0)
Using bitmap As New Bitmap(toolAttrib.GetImage(customActivityType))
Dim ImageDrawing As New ImageDrawing(System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions),
New Rect(0, 0, 16, 16))
Me.Icon = New DrawingBrush(ImageDrawing)
End Using
End Sub
End Class
"TestClass.VB"
Imports System.Reflection
Imports Microsoft.Win32
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports System.IO
Public NotInheritable Class TesteClass
'precisa ser public, senao IExtensionApplication nao funciona
Implements IExtensionApplication
Public Shared ReadOnly PRODUCTKEY As String = HostApplicationServices.Current.UserRegistryProductRootKey
Public Shared ReadOnly LOADER As String = Reflection.Assembly.GetExecutingAssembly.Location
Public Shared ReadOnly PASTA As String = New FileInfo(LOADER).DirectoryName
Public Sub Initialize() Implements IExtensionApplication.Initialize
Try
Dim cUserApp = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(PRODUCTKEY & "\Applications", True)
With cUserApp.CreateSubKey(My.Application.Info.Title)
.SetValue("DESCRIPTION", My.Application.Info.Description)
.SetValue("MANAGED", 1, RegistryValueKind.DWord)
.SetValue("LOADCTRLS", 2, RegistryValueKind.DWord)
.SetValue("LOADER", System.Reflection.Assembly.GetExecutingAssembly.Location)
Try
.DeleteSubKey("Commands")
Catch
End Try
With .CreateSubKey("Commands")
For Each tp As Type In Assembly.GetExecutingAssembly.GetExportedTypes()
For Each meth As MethodInfo In tp.GetMethods()
For Each obj As CommandMethodAttribute In meth.GetCustomAttributes(GetType(CommandMethodAttribute), True)
.SetValue(obj.GlobalName, obj.GlobalName)
Next
Next
Next
End With
End With
Catch
End Try
End Sub
Public Sub Terminate() Implements IExtensionApplication.Terminate
End Sub
<CommandMethod("teste")>
Public Sub teste()
Dim f As New Form1
f.ShowDialog()
End Sub
End Class
"Form1.vb"
Imports System.Activities
Imports System.Activities.Core.Presentation
Imports System.Activities.Presentation
Imports System.Activities.Presentation.Toolbox
Imports System.Activities.Statements
Imports System.Windows
Imports System.Windows.Forms
Public Class Form1
Private Shared _firsload As Boolean = True
Public Sub New()
Dim dd As New DesignerMetadata()
dd.Register()
' Esta chamada é requerida pelo designer.
InitializeComponent()
' Adicione qualquer inicialização após a chamada InitializeComponent().
Dim WorkflowDesigner As New WorkflowDesigner
Dim ActivityBuilder As New ActivityBuilder With {.Implementation = New Flowchart}
WorkflowDesigner.Load(ActivityBuilder)
Dim ctrl As New ToolboxControl()
'Dim item As New ToolboxItemWrapper("TesteCAD.MyCustomActivity", TesteClass.LOADER, "", "teste")
Dim item As New ToolboxItemWrapper(GetType(MyCustomActivity), "teste")
ctrl.Categories.Add(New ToolboxCategory("teste") From {item})
ElementHost1.Child = ctrl
ElementHost2.Child = WorkflowDesigner.View
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim wd As New WorkflowDesigner
Using lixo As New Form With {.Size = New System.Drawing.Size(1, 1), .ShowInTaskbar = False, .FormBorderStyle = FormBorderStyle.None}
Dim elementHost As New Integration.ElementHost
lixo.Controls.Add(elementHost)
elementHost.Child = wd.View
AddHandler lixo.Activated, Sub()
Forms.Application.DoEvents()
lixo.Close()
End Sub
lixo.ShowDialog()
End Using
End Sub
End Class
"Form1.Designer.vb"
Imports System.Windows.Forms
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Class Form1
Inherits System.Windows.Forms.Form
'Descartar substituições de formulário para limpar a lista de componentes.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Exigido pelo Windows Form Designer
Private components As System.ComponentModel.IContainer
'OBSERVAÇÃO: o procedimento a seguir é exigido pelo Windows Form Designer
'Pode ser modificado usando o Windows Form Designer.
'Não o modifique usando o editor de códigos.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.SplitContainer1 = New System.Windows.Forms.SplitContainer()
Me.ElementHost1 = New System.Windows.Forms.Integration.ElementHost()
Me.ElementHost2 = New System.Windows.Forms.Integration.ElementHost()
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SplitContainer1.Panel1.SuspendLayout()
Me.SplitContainer1.Panel2.SuspendLayout()
Me.SplitContainer1.SuspendLayout()
Me.SuspendLayout()
'
'SplitContainer1
'
Me.SplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill
Me.SplitContainer1.Location = New System.Drawing.Point(0, 0)
Me.SplitContainer1.Name = "SplitContainer1"
'
'SplitContainer1.Panel1
'
Me.SplitContainer1.Panel1.Controls.Add(Me.ElementHost1)
'
'SplitContainer1.Panel2
'
Me.SplitContainer1.Panel2.Controls.Add(Me.ElementHost2)
Me.SplitContainer1.Size = New System.Drawing.Size(800, 450)
Me.SplitContainer1.SplitterDistance = 266
Me.SplitContainer1.TabIndex = 0
'
'ElementHost1
'
Me.ElementHost1.Dock = System.Windows.Forms.DockStyle.Fill
Me.ElementHost1.Location = New System.Drawing.Point(0, 0)
Me.ElementHost1.Name = "ElementHost1"
Me.ElementHost1.Size = New System.Drawing.Size(266, 450)
Me.ElementHost1.TabIndex = 0
Me.ElementHost1.Text = "ElementHost1"
Me.ElementHost1.Child = Nothing
'
'ElementHost2
'
Me.ElementHost2.Dock = System.Windows.Forms.DockStyle.Fill
Me.ElementHost2.Location = New System.Drawing.Point(0, 0)
Me.ElementHost2.Name = "ElementHost2"
Me.ElementHost2.Size = New System.Drawing.Size(530, 450)
Me.ElementHost2.TabIndex = 0
Me.ElementHost2.Text = "ElementHost2"
Me.ElementHost2.Child = Nothing
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(800, 450)
Me.Controls.Add(Me.SplitContainer1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.SplitContainer1.Panel1.ResumeLayout(False)
Me.SplitContainer1.Panel2.ResumeLayout(False)
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).EndInit()
Me.SplitContainer1.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Friend WithEvents SplitContainer1 As SplitContainer
Friend WithEvents ElementHost1 As Integration.ElementHost
Friend WithEvents ElementHost2 As Integration.ElementHost
End Class