Error 80040154 Class not registered - how to fix for ARX SAPILib.dll - cosign-api

I've been using CoSign within Microsoft Word successfully, but now I'm trying to automate the report generation using Microsoft Visual Basic Studio 10 Express. Trying to download the developer's software bundle fails due to the previous client installation, but I do already see the Arx Signature API 6.20 installed on my desktop, and I can add a reference to the Interop.SAPILib.dll without a problem, through the COM tab; Intellisense recognizes all the appropriate functions, so everything seemed to be installed. However, when I build and debug the program, I am given the error 80040154 Class not registered, specifically on the first "Dim myFileHandle as New SAPILibrary.FileHandle" call. Previous calls work without error; they include creating MySAPI as a New SAPICrypt, MyHandle as a new SESHandle object, MyFieldHandle as new SAPILib.SigFieldSettings, and calls to MySAPI.init, MySAPI.HandleAquire, MySAPI.Logon. My code is below.
Other forum posts for this error cite the need for assuring x86 builds if using a 32-bit dll. I have confirmed that it is my solution's compile platform; I am using a 64-bit Toshiba running Windows 7.
Can it be a dll issue, since the other SAPILibrary class reference worked well?
Does the Arx Cosign installation not automatically register the dll, despite my being able to reference it in Visual Stuio Express? I tried to manually register the dll file, but I'm then given the error that the module was loaded but that the entry point DllRegisterServer was not found, and to check to see if this is a valid dll.
Obviously I'm new to COM dlls. Am I on the right track, or is this an unhandled error of another kind?
Private Sub SignWithSAPI()
Dim username As String = "XXX#yahoo.com"
Dim password As String = "passwordhere"
'add a signature field locator string - NEED TO HIDE THIS AS IT DOESN'T GET ERASED BY SAPI
Dim MyFieldLocatorString As String = "<<<W=200;H=120;N=Physician signature;A=&HC;>>>"
oWord.Selection.TypeText(MyFieldLocatorString)
'SIGN PDF HERE USING COSIGN Signature API
Dim mySAPI As New SAPICrypt
Dim myHandle As New SESHandle
Dim rc As Int32
rc = mySAPI.Init()
If rc <> 0 Then
MessageBox.Show("Init failed")
Exit Sub
End If
rc = mySAPI.HandleAcquire(myHandle)
If rc <> 0 Then
MessageBox.Show("failed at handleAcquire")
mySAPI.Finalize()
Exit Sub
End If
rc = mySAPI.Logon(myHandle, userName, "", password)
If rc <> 0 Then
MessageBox.Show("Login failed")
mySAPI.HandleRelease(myHandle)
mySAPI.Finalize()
Exit Sub
End If
Dim MyFieldSettings As New SAPILib.SigFieldSettings
With MyFieldSettings
.Invisible = 0
.Height = 200
.Width = 100
.AppearanceMask = myChosenAppearancesMask 'shows graphical image, name of signer and time
.SignatureType = SAPI_ENUM_SIGNATURE_TYPE.SAPI_ENUM_SIGNATURE_DIGITAL
End With
Dim myPDFfileName As String = "C:\\Users\Scott\Desktop\TestAutomation.pdf"
Dim myFileHandle As New SAPILib.FileHandle
rc = mySAPI.CreateFileHandleByName(myFileHandle, _
SAPI_ENUM_FILE_TYPE.SAPI_ENUM_FILE_ADOBE, 0, myPDFfileName)
If rc <> 0 Then
MessageBox.Show("Error in creating FileHandlebyName")
mySAPI.HandleRelease(myHandle)
mySAPI.Finalize()
Exit Sub
End If
'Assigns the SigFieldContext
Dim mySigFieldContext As New SAPIContext
Dim myNumberOfSigFields As Integer
rc = mySAPI.SignatureFieldEnumInitEx(myHandle, mySigFieldContext, _
SAPI_ENUM_FILE_TYPE.SAPI_ENUM_FILE_ADOBE, "", myFileHandle, 0, myNumberOfSigFields)
If rc <> 0 Then
MessageBox.Show("Error in SigFieldEnumInitEx")
mySAPI.HandleRelease(myFileHandle)
mySAPI.HandleRelease(myHandle)
mySAPI.Finalize()
Exit Sub
End If
Dim mySigFieldLocatorContext As New SAPIContext 'next line assigns its value in the function
rc = mySAPI.SignatureFieldLocatorEnumInit(myHandle, mySigFieldLocatorContext, _
myFileHandle, "<<<", ">>>", 0, myNumberOfSigFields)
If rc <> 0 Then
mySAPI.ContextRelease(mySigFieldContext)
MessageBox.Show("Error in SigFieldLocatorContext")
mySAPI.HandleRelease(myFileHandle)
mySAPI.HandleRelease(myHandle)
mySAPI.Finalize()
Exit Sub
End If
Dim mySigFieldHandle As New SigFieldHandle
rc = mySAPI.SignatureFieldEnumCont(myHandle, mySigFieldContext, mySigFieldHandle)
'assigns the first(only) value to mySigFieldHandle
If rc <> 0 Then
mySAPI.ContextRelease(mySigFieldLocatorContext)
mySAPI.ContextRelease(mySigFieldContext)
MessageBox.Show("Error in SigFieldLocatorContext")
mySAPI.HandleRelease(myFileHandle)
mySAPI.HandleRelease(myHandle)
mySAPI.Finalize()
Exit Sub
End If
'//Create the Field
rc = mySAPI.SignatureFieldSignEx(myHandle, mySigFieldHandle, myChosenAppearancesMask, _
Nothing)
If rc <> 0 Then
MessageBox.Show("Error in sigfieldSignEx")
End If
'release resources
mySAPI.HandleRelease(mySigFieldHandle)
mySAPI.HandleRelease(myFileHandle)
mySAPI.ContextRelease(mySigFieldContext)
mySAPI.ContextRelease(mySigFieldLocatorContext)
mySAPI.Logoff(myHandle)
mySAPI.HandleRelease(myHandle)
End Sub
Thanks!

The FileHandle object can be created using either CreateFileHandleByName or CreateFileHandleByMem functions and this is the proper way to instantiate the object in our COM. Replacing the line Dim myFileHandle As New SAPILib.FileHandle with Dim myFileHandle As SAPILib.FileHandle = Nothing will solve your issue.

Related

unable to cast COM object of type microsoft.office.interop.outlook.applicationclass to interface type Microsoft.Office.Interop.Outlook._Application

Perform a development where it is necessary for me to obtain the mail that is registered in the Outlook session in Windows. In that sense, the only thing that the user has to do is enter their windows session password to be able to log in and then go to a SharePoint and download several files. At the time of executing the programming, it sends me the following error.
Please verify whit the support the next error: Unable to cast COM
object type 'Microsoft.Office.Interop.Outlook.ApplicationClass' to
interface type 'Microsoft.Office.Interop.Outlook._Application'. This
operation failed because the QueryInterface call on the COM component
for the interface with ID '{00063001-0000-0000-C000-000000000046}'
failed due to the following error: Error loading type library/DLL.
(Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).
I already checked in regedit, but the subkey is at 0, I investigated this a little in other internet sites but I still have the same problem.
Can you help me to see where the error is? This is the code that I developed.
The Outlook version is 2016 (O365) and Windows 10.
Imports System.Security
Imports Microsoft.SharePoint.Client
Imports System.Runtime.InteropServices
Imports Microsoft.Office.Interop
Imports System.IO
Imports Microsoft.SharePoint
Imports System.Net
Imports System.Net.Http
Imports Microsoft.ProjectServer.Client
Imports System
Imports System.Management
Imports System.Text
Imports Outlook = Microsoft.Office.Interop.Outlook
Module UpdateDB
Dim password As String
Dim url As String
Dim username As String
Dim ctx As ClientContext
Dim securedPassword
Public Function updateDb(value As Integer)
Try
ActivateOL()
Dim outlook As Outlook.Application = New Outlook.Application()
Dim addrEntry As Outlook.AddressEntry = outlook.Session.CurrentUser.AddressEntry
If addrEntry.Type = "EX" Then
Dim currentUser As Outlook.ExchangeUser = outlook.Session.CurrentUser.AddressEntry.GetExchangeUser()
If currentUser IsNot Nothing Then
Dim sb As StringBuilder = New StringBuilder()
username = currentUser.PrimarySmtpAddress
End If
End If
Dim siteUrl As String = "https://name_company.sharepoint.com/sites/test/"
password = Form1.MyInputBox("Please Enter Your Password")
Form1.ProgressBar1.Minimum = 0
Form1.ProgressBar1.Maximum = 28
Form1.ProgressBar1.Visible = True
Form1.Label115.Visible = True
Form1.Label115.BringToFront()
Form1.ProgressBar1.Value = 0
url = "https://name_company.sharepoint.com/sites/test/SiteFiles/test.txt"
ctx = New ClientContext(url)
securedPassword = New SecureString()
For Each c In password.ToCharArray()
securedPassword.AppendChar(c)
Next
My.Computer.FileSystem.DeleteFile("C:\Temp\test.txt")
ctx.Credentials = New SharePointOnlineCredentials(username, securedPassword)
DownloadFile(url, ctx.Credentials, "C:\Temp\test.txt")
Form1.ProgressBar1.Value = 1
Catch ex As Exception
MsgBox("Please verify whit the support the next error: " & ex.Message, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly, "TEST")
Form1.ProgressBar1.Value = 0
Form1.ProgressBar1.Visible = False
value = 1
Return value
GoTo finFunction
End Try
ctx.Credentials = New SharePointOnlineCredentials(username, securedPassword)
url = "https://name_company.sharepoint.com/sites/test/DATA%20BASE/DEVICES.xlsx"
ctx = New ClientContext(url)
ctx.Credentials = New SharePointOnlineCredentials(username, securedPassword)
DownloadFile(url, ctx.Credentials, "C:\Users\Public\Documents\TEST.xlsx")
Form1.ProgressBar1.Value = 3
MsgBox("UPDATED COMPLETED", MsgBoxStyle.Information + MessageBoxButtons.OK, "ABB - MNS PRO")
Form1.ProgressBar1.Visible = False
Form1.Label115.Visible = False
finFunction:
End Function
Sub DownloadFile(ByVal webUrl As String, ByVal credentials As ICredentials, ByVal fileRelativeUrl As String)
Using client = New WebClient()
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
client.Headers.Add("User-Agent: Other")
client.Credentials = credentials
client.DownloadFile(webUrl, fileRelativeUrl)
End Using
End Sub
Sub DeleteFilesInsideFolder(ByVal target_folder_path As String)
' loop through each file in the target directory
For Each file_path As String In Directory.GetFiles(target_folder_path)
' delete the file if possible...otherwise skip it
Try
My.Computer.FileSystem.DeleteFile(file_path)
Catch ex As Exception
MessageBox.Show(ex.Message, "TEST")
End Try
Next
End Sub
<DllImport("netapi32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Unicode)>
Public Function NetUserChangePassword(
<MarshalAs(UnmanagedType.LPWStr)> ByVal OldPass As String) As Integer
End Function
Public Sub ChangePassword(ByVal oldPassword As String)
Try
NetUserChangePassword(oldPassword)
Catch ex As Exception
Throw
End Try
End Sub
Sub ActivateOL()
'Error 429 occurs with GetObject if Outlook is not running.
On Error Resume Next
Dim objOutlook = GetObject(, "Outlook.Application")
If Err.Number = 429 Then 'Outlook is NOT running.
MsgBox("Outlook is not running")
End If
End Sub
End Module
Thanks for the support.
First Update
Public Function updateDb(value As Integer)
Try
ActivateOL()
Dim outlook As Outlook.Application = Nothing
Try
outlook = DirectCast(Marshal.GetActiveObject("Outlook.Application"), Outlook.Application)
Catch
outlook = New Outlook.Application()
End Try
End Sub
Sub ActivateOL()
'Error 429 occurs with GetObject if Outlook is not running.
Dim objOutlook = GetObject(, "Outlook.Application")
If Err.Number = 429 Then 'Outlook is NOT running.
MsgBox("Outlook is not running")
End If
End Sub
It not seems a problem of your code but a problem on Windows-Outlook configuration matter.
I've solved using point 3 "Ensure MSOUTL.LIB is Registered" of this fantastic guide (the most precise and techincal that I've found after 'few' hours of search)
webmakers - Interface not registered (Exception from HRESULT: 0x80040155) – Microsoft Office/Outlook Error, after checked the previous point, obviously.
Thanks to Jatin-Auckland for a clear and step by step guide.

Open raster file error: A Debugger is attached to w3wp exe but not configured

I have written a vb.net function to open a raster file. The function is as follows:
Public Function OpenRaster(ByVal directoryName As String, ByVal fileName As String) As IRaster
Dim workspaceFactory As IWorkspaceFactory
Dim rasterWorkspace As IRasterWorkspace
Dim rasterDataset As IRasterDataset = Nothing
Try
workspaceFactory = New RasterWorkspaceFactory
ESRI.ArcGIS.DataSourcesGDB.AccessWorkspaceFactoryClass()
rasterWorkspace = TryCast(workspaceFactory.OpenFromFile(directoryName, 0), IRasterWorkspace)
rasterDataset = rasterWorkspace.OpenRasterDataset(fileName)
Catch e As Exception
End Try
Dim pRasterLayer As IRasterLayer = New RasterLayer()
pRasterLayer.CreateFromDataset(rasterDataset)
Dim pRaster As IRaster = Nothing
pRaster = pRasterLayer.Raster
Return pRaster
End Function
The above function is throwing below error in TryCast statement :
A Debugger is attached to w3wp exe but not configured to debug this unhandled exception. To debug this expression detach the current debugger.
I searched on google also, some suggestions were to enable 32-bit in IIS application pool, but enabling this also is not making the code work

How do I kill a process that doesn't have any windows in VB.net?

I am new to VB.net and I am trying to write a forms app that works with Autodesk Inventor.
Unfortunately, every time I close Inventor, the "Inventor.exe" process still stays. I didn't realize this while debugging and I only realized this when I checked the task manager after the whole system started to lag.
Killing every process with the same name is fairly simple, but the issue is that the end user might have separate documents open in another Inventor window. So I need to write a function that only kills the Inventor processes that don't have a window open.
Public Class Form1
Dim _invApp As Inventor.Application
Dim _started As Boolean = False
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Try
_invApp = Marshal.GetActiveObject("Inventor.Application")
Catch ex As Exception
Try
Dim invAppType As Type = _
GetTypeFromProgID("Inventor.Application")
_invApp = CreateInstance(invAppType)
_invApp.Visible = True
'Note: if you shut down the Inventor session that was started
'this(way) there is still an Inventor.exe running. We will use
'this Boolean to test whether or not the Inventor App will
'need to be shut down.
_started = True
Catch ex2 As Exception
MsgBox(ex2.ToString())
MsgBox("Unable to get or start Inventor")
End Try
End Try
End Sub
Another section where I start a process, which is a specific 3D model file.
Public Sub SaveAs(oTemplate As String)
'define the active document
Dim oPartDoc As PartDocument = _invApp.ActiveDocument
'create a file dialog box
Dim oFileDlg As Inventor.FileDialog = Nothing
Dim oInitialPath As String = System.IO.Path.GetFullPath("TemplatesResources\" & oTemplate)
_invApp.CreateFileDialog(oFileDlg)
'check file type and set dialog filter
If oPartDoc.DocumentType = kPartDocumentObject Then
oFileDlg.Filter = "Autodesk Inventor Part Files (*.ipt)|*.ipt"
ElseIf oPartDoc.DocumentType = kAssemblyDocumentObject Then
oFileDlg.Filter = "Autodesk Inventor Assembly Files (*.iam)|*.iam"
ElseIf oPartDoc.DocumentType = kDrawingDocumentObject Then
oFileDlg.Filter = "Autodesk Inventor Drawing Files (*.idw)|*.idw"
End If
If oPartDoc.DocumentType = kAssemblyDocumentObject Then
oFileDlg.Filter = "Autodesk Inventor Assembly Files (*.iam)|*.iam"
End If
'set the directory to open the dialog at
oFileDlg.InitialDirectory = "C:\Vault WorkSpace\Draft"
'set the file name string to use in the input box
oFileDlg.FileName = "######-AAAA-AAA-##"
'work with an error created by the user backing out of the save
oFileDlg.CancelError = True
On Error Resume Next
'specify the file dialog as a save dialog (rather than a open dialog)
oFileDlg.ShowSave()
'catch an empty string in the imput
If Err.Number <> 0 Then
MessageBox.Show("Any changes made from here will affect the original template file!", "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification)
ElseIf oFileDlg.FileName <> "" Then
Dim MyFile As String = oFileDlg.FileName
'save the file
oPartDoc.SaveAs(MyFile, False)
'open the drawing document
System.Diagnostics.Process.Start(oInitialPath & ".idw")
Dim oFinalPath As String = oPartDoc.FullFileName
MessageBox.Show(oFinalPath, "", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification)
MessageBox.Show("Loaded", "", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification)
Dim oDrawingDoc As DrawingDocument = _invApp.Documents.ItemByName(oInitialPath & ".idw")
'oDrawingDoc.SaveAs()
End If
End Sub
Any help is appreciated.
Thanks
At the end on your form, probably FormClosed, add the following:
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
If (_invApp Is Nothing) Then Return ' if empty, then no action needed
_invApp.Quit()
Marshal.ReleaseComObject(_invApp)
_invApp = Nothing
System.GC.WaitForPendingFinalizers()
System.GC.Collect()
End Sub
This should make .NET release and properly dispose the COM Object for Inventor.
And consider declare the Inventor variable and assign Nothing/null, it's safer (avoid mistakes)
Dim _invApp As Inventor.Application = Nothing

system.diagnostics.process will not open Excel file without Excel open first

I have a VB.Net application in which I have a general method to open documents that exist on the local drive using system.diagnostics.process.
Public Shared Function OpenFileWithProcess(ByVal lsFileNameWithPath As String, Optional ByVal lPrintOption As PrintOutputOption = PrintOutputOption.Preview)
Try
Select Case lPrintOption
Case PrintOutputOption.Preview
Dim P As System.Diagnostics.Process
P = Process.Start(lsFileNameWithPath)
If Not P Is Nothing Then
Dim handle As IntPtr = P.Handle
SetForegroundWindow(handle)
End If
Case PrintOutputOption.Print
Dim Proc As New Process
Proc.StartInfo.FileName = lsFileNameWithPath
Proc.StartInfo.UseShellExecute = True
Proc.StartInfo.Verb = "Print"
Proc.Start()
End Select
Catch ex As Exception
If oSQL.Key_Developer Then
Stop
End If
Throw ex
End Try
End Function
On some computers that have Windows8 and OFfice2010, this method will not open an Excel file without Excel being open first. Instead it will error with "Run-Time Error 2147467259 (80004005). An error occurred in sending the command to the application".
If Excel is open prior to the method call, then the file opens just fine.
Some additional environment info:
- VB.NET application compiled to .Net Framework 4
- Application is deployed on Windows 7, 8 and 8.1
I could trap for the error and try to start the process again using the Excel session that hangs open after the error but I'm wondering if someone can tell me or help me figure out what is going on here.
Thank you for your time.

VB.NET / C# after finding installed Software names and application path how to find exe name

This code gets all software that has an Uninstall Entry and it app path. However, given I have the app path, I do not know the name of the main .exe of the software. What ways are there to find the main .exe of a found application?
'Declare the string to hold the list:
Dim Software As String = Nothing
'The registry key:
Dim SoftwareKey As String = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Using rk As RegistryKey = Registry.LocalMachine.OpenSubKey(SoftwareKey)
'Let's go through the registry keys and get the info we need:
Dim j As Integer = 0
For Each skName As String In rk.GetSubKeyNames()
Using sk As RegistryKey = rk.OpenSubKey(skName)
Try
'If the key has value, continue, if not, skip it:
If Not (sk.GetValue("DisplayName") Is Nothing) And Not (sk.GetValue("InstallLocation") Is Nothing) And
Not (sk.GetValue("InstallLocation") = "") Then
Dim instanceremoved As Boolean = False
For Each item As ListViewItem In ListInstalled.Items
If item.SubItems.Item(1).Text = sk.GetValue("InstallLocation") Then
item.Remove()
instanceremoved = True
End If
Next
If instanceremoved = False Then
Dim itemAdd As ListViewItem = ListInstalled.Items.Add(sk.GetValue("DisplayName"))
itemAdd.SubItems.Add(sk.GetValue("InstallLocation"))
End If
End If
'No, that exception is not getting away... :P
Catch ex As Exception
MsgBox(ex)
End Try
End Using
j = j + 1
Next
End Using
The main Exe is not stored in the registry the uninstall command is stored in the UninstallString key.