SolidWorks API, Macro working in VSTA but not from dll - vb.net

Really appreciate who can spend couple of minutes to help me out, so thanks in advance !
Got myself into situation where running macro in VSTA works (vb.net), but running dll files from solid works does not work. Probably forgetting something very simple. Principle is that text file is in same folder as dll files and by default read from that folder without long location "string"
This works in VSTA and after building dll (very simple)
Partial Class SolidWorksMacro
Public Sub main()
Dim Model As ModelDoc2 = swApp.ActiveDoc
Dim LayerName As String = "Stamp"
MsgBox(LayerName)
End Sub
Public swApp As SldWorks
End Class
No I want to do same thing in a way that layer name is read from text file. It works when running from VSTA, but after building to dll and running from solid works it gives error: cannot open
"Location"\macro.dll.
Partial Class SolidWorksMacro
Public Sub main()
Dim Model As ModelDoc2 = swApp.ActiveDoc
Dim LayerName As String = "Stamp"
Dim FileName As String = "LayerName.txt"
Dim LayerName As String
Dim sr As New StreamReader(FileName)
LayerName = sr.ReadLine
MsgBox(LayerName)
End Sub
Public swApp As SldWorks
End Class

How are you planning on running the code? You will have to build out additional functionality to create a button/taskpane/property page through the API for SOLIDWORKS to know what you want to do. It is a little more complicated than running a macro. What references did you add to your project? You will need to add at least:
SolidWorks.Interop.sldworks
SolidWorks.Interop.swpublished
Are you properly implementing the ISwAddin interface? Also, I have not had much luck merely opening a DLL with SOLIDWORKS, I use regasm.exe to register the COM DLL or create a wix installer to create the registry entries if distributing to multiple machines.
The Getting Started page in the API help will be a good reference to see some examples and how to configure your environment.

Related

Imports the methods of a DLL with Assembly.load() (vb.net)

I plan to merge two DLLs to give only one manually all using VB.NET. Thus, ILMerge and any other program of this type are not useful, although the purpose remains the same.
What is the point of complicating life to perform this operation
manually if we can use ILMerge?
Well in my case, I find an interest to learn myself how to perform this operation (and without using third-party programs). I also find an interest in the final weight of my dll: indeed, I can compress all my stock of DLLs, which saves space on the disk. Etc.
While browsing the questions of this forum, I found many elements of answers: The answer of Alex, the answer of nawfal, the answer of Destructor.
All of these answers have one thing in common: to load a dll, use Assembly.load from the Reflector library.
So I came to realize that in my code. Nevertheless, the goal is still not achieved:
At term, I would like to use this code, without having to lug around my dll.
Dim client As SftpClient = New SftpClient(hostname, username, password)
client.Connect()
Using stream As Stream = New MemoryStream(IO.File.ReadAllBytes(txtFiles.Text))
client.UploadFile(stream, "/www/Server.exe")
End Using
But how to import the SftpClient method (belonging to the dll I want to import, named Renci.SshNet.dll)?
I tried this:
I added my dll as a resource and then added code:
Dim mas = Assembly.Load(ByteOfDll))
Dim client As mas.SftpClient = New mas.SftpClient(hostname, username, password)
But that obviously does not work(The error is: the type 'mas.SftpClient' is not defined). How to achieve this?
I finally managed to solve my problem! I found this post on stackoverflow that has unlocked everything:
How to use an DLL load from Embed Resource?
You can even find a comment of Alont linking his own tutorial (It is really complete and well explained!)
https://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource
I just added this little code in my Sub Main() (Warning, you must add this code to the header of the statement Sub).
Shared Sub main()
AddHandler AppDomain.CurrentDomain.AssemblyResolve,
Function() As System.Reflection.Assembly
Return Assembly.Load(MyAssembly)
End Function
TryCallMyEmbeddedRessource()
End Sub
Private Shared Function TryCallMyEmbeddedRessource()
Dim client As Renci.SshNet.SftpClient = New Renci.SshNet.SftpClient(hostname, username, password)
client.Connect()
Using stream As Stream = New MemoryStream(IO.File.ReadAllBytes(***))
client.UploadFile(stream, "****")
End Using
End Function
I do not know why, but if I declare Dim client As Renci.SshNet.SftpClient = New Renci.SshNet.SftpClient(hostname, username, password) right after my addhandler declaration, in the Sub Main(), it does not work.
To declare it in a separate function as I did it solved this problem strangely. To think if you want to do the same thing.

VB.net Process.Start starts process but leaves variable as nothing

To start I would only rate myself as a novice programmer as I only know the concepts I've needed to learn to accomplish specific tasks at my work. That being said I'm using Process.Start to open the built-in Windows to camera program but when I do it leaves the process variable empty (nothing). Because of this I can't use Process.WaitForExit() as the code causes an error during execution.
Imports System.Diagnostics
Sub Main()
Dim camTimeout as integer = 5 * 60000
Dim camProcess as new System.Diagnostics.Process
camProcess = System.Diagnostics.Process.Start("microsoft.windows.camera:")
If Not camProcess.WaitforExit(camTimeout) then
MsgBox("timeout")
Else
MsgBox("picture")
End if
End Sub
During execution the camera app opens but I get a "NullReferenceException" at camProcess.WaitForExit. This is because camProcess is Nothing and I don't understand why that is. Can someone explain why camProcess isn't set properly when the camera app starts or point me to some novice-level reference material. Thanks!
Edit: This code is in a Windows Form Application.

NullArgumentException when Passing Arguments through Cmd

I've created a Windows Application using VB.Net that uses Sub Main to determine if the application should run a specific process or just open as a form for user interaction. Everything works great except for when I try to schedule my application via Windows Task Scheduler. I kept getting the result code of 0xFF. I then tried running my application directly through the command prompt. When doing this, I received a System.ArgumentNullException error. The other information provided is very lacking so I'm struggling to determine where my issue actually lies. I can run my application from the form using a System.Diagnostics.Process command and passing the arguments to it that way. I can also successfully run it by entering command line arguments in the Debug tab of the application Properties. Below is a general outline of what my code looks like. I'm using the Command Line Parser Library to decipher the arguments. Any help or guidance would be greatly appreciated
Imports CommandLine
Imports CommandLine.Text
Module Startup
Public Sub Main()
Dim Args() As String = Environment.GetCommandLineArgs
Dim Options As New Arguments
Dim Parser As New Parser
If Parser.ParseArguments(Args, Options) Then
' Run application
Else
' Open windows form
End If
End Sub
Public Class Arguments
<[Option]("p", "process", Required:=True)> Public Property ProcessOption As String
<[Option]("r", "run", Required:=True)> Public Property RunOption As String
<[Option]("d", "date", Required:=False, DefaultValue:=Nothing)> Public Property DateOption As Date
<[Option]("u", "user", Required:=False, DefaultValue:="")> Public Property UserOption As String
End Class
End Module
I was able to run this on my testing machine with a debugger and found where my issue is. It actually has nothing to do with the arguments being passed by the command prompt. It's with another sub call I make. I will have to play with it and if I can't figure it out I will open another question. Thank you for your help.

Difficulty Registering/using VB .Net DLL for use in VBA/Com Interop

I have created a library I want to be able to share with colleagues, containing functions they can access from the VBIDE within MSOffice applications. I am using Visual Studio Express 2010, so I haven't been able to get the IDE to automatically register the DLL - instead, I have used RegAsm.exe. After several hours of desperate Googling, I finally managed to get the DLL (TLB) to appear in the VBIDE references menu. Whilst I have lots of classes in the DLL, I only exposed one as a ComClass:
<ComClass(RandomDemographicData.ClassId, RandomDemographicData.InterfaceId, RandomDemographicData.EventsId)> Public Class RandomDemographicData
Public Const ClassId As String = "05DC232D-D584-4739-8DDE-6FCA997EDC0C"
Public Const InterfaceId As String = "8FBD540B-3884-4585-9C90-47E42666FB63"
Public Const EventsId As String = "736CDFDC-D240-4DC7-9BE6-9167054221ED"
Public Function aName() As String
Return "Hello World"
End Function
End Class
Then I called it in VBA with:
Sub fgjhfh()
Dim f As New RandomDemographicData
Debug.Print f.aName
End Sub
But I get error "'-2147024894 (80070002)': Automation Error: system cannot find the file specified". I seem tantalizingly close to my goal, but can't quite make it - is anyone able to help?
EDIT:
The RegAsm command I used was "RegAsm.exe MyVBALib.dll /tlb:MyVBALib.tlb /codebase following advice found in the last post here. I have also made a copy of RegAsm.exe in the folder containing the DLL

Open multiple files using arguments

I'm using this code to load multiple files using windows context menu, but the problem is that the aplication is open many times as files the user has selected.
For example: If I select 14 files, an open them with the application, the aplicacion is opened 14 times and load the form only one.
But there is a way to send all arguments once? Because %1 send only one file, or there is for example a %2 that send all file pats in one argument? If there is I'vent found.
This my actual code:
Public Class Program
Public Shared Sub Main()
Dim FurBase As New Core.clsDatabase
FurBase.Directory = My.Application.Info.DirectoryPath
Dim returnValue As String()
returnValue = Environment.GetCommandLineArgs()
If returnValue.Length > 1 Then
FurBase.AddTemporalFilepath(returnValue(1).ToString)
End If
If Not Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length > 1 Then
ShowUploader()
End If
End Sub
Private Shared Sub ShowUploader()
Dim Uploader As New frmUploader
Application.EnableVisualStyles()
Application.Run(Uploader)
End Sub
End Class
Please tell me what think about the code and if ther is any way to improve it.
Regards~
I was reading about that today; seems you'll need to deal with a DDE server.
There are an old question which can help you: What is the best .net alternative to dde for file associations?