"insert a smart card" window pops up when install Excel AddIn - excel

My Excel AddIn is written in C#, it uses Excel DNA, AddIn Express RTD, NetOffice
Installer is created with Advanced Installer, plus VBA
the VBA code is in install.xls
Private Sub Workbook_Open()
Dim quit As Integer
Dim added As Boolean
Add_Addin
If Workbooks.Count = 1 Then
Application.quit
Else
Me.Close
End If
End Sub
Private Sub Add_Addin()
On Error GoTo ERR_
Dim addinFile As String
addinFile = ThisWorkbook.Path & "\" & "MyAddIn.xll"
If Len(addinFile) > 0 Then
Dim LEA As AddIn
Set LEA = Application.AddIns.Add(addinFile)
If (Not LEA Is Nothing) Then
LEA.Installed = True
Else
MsgBox "Failed to add XLL"
End If
Else
MsgBox "XLL file not found"
End If
Exit Sub
ERR_:
MsgBox ("Error " & Err.Number & " " & Err.Description)
End Sub
Everything works fine. and I did not change installer
Now when one user installs new version of my addin,
when install.xls is run in Excel, a window pops up saying "insert smart card"
I think and think and figure out the only thing changed (compared with previous version) is digital sigature of the install.xls b/c the previous signature file expired recently
I signed install.xls with the new certificate
Now the strange window pops up during install.
Anyone know how to solve this?
Thanks

Perhaps you can try following the instructions on the link below for adding a trusted location.
http://office.microsoft.com/en-us/word-help/add-remove-or-modify-a-trusted-location-for-your-files-HA010354311.aspx#BM1
This is a fix I am pursuing for a similar issue.

Related

Bypass need for a trusted document?

Im working on building out a VBA-based app that will have around 150 users. They will all have their own data files, tables, custom views, etc. But I will need to regularly update the code behind the app. So Im using the two-workbook technique where their unique User Workbooks (call them the UWs) all pass control to a Code Workbook (call it CW) which contains all the code. That way, when I need to update, I update the CW, and everyone simply replaces the old CW in their folders with the new one and their UWs remain the same.
My problem is that I'd like the CW to essentially remain hidden and protected. But with macro security, when they open their UWs after the update and it immediately calls the startup subroutine in the new CW, it won't run. They have to first open the CW (which I don't want!) and make it a trusted document before opening their UWs will run the startup subroutine in the CW.
It shouldn't matter, but here is the only code in the UWs (note this is still in prototyping/early stages so everything is called 'Test'!):
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next
Workbooks("Test CW.xlsm").Close
End Sub
Private Sub Workbook_Open()
Application.ScreenUpdating = False
'Checks to see if TestCW is present next to Test UW
On Error Resume Next
X = Workbooks("Test CW.xlsm").Name 'Sets X to name of workbook; if its not there this will throw an error and Err <> 0
If Not (Err = 0) Then 'If there's no error
On Error GoTo CWFileError
Workbooks.Open Filename:=ThisWorkbook.Path & Application.PathSeparator & "Test CW.xlsm" 'Opens Test CW if in same folder
'Makes Test CW hidden
Workbooks("Test CW.xlsm").Windows(1).Visible = False
End If
On Error GoTo 0
'Runs test module in Test CW, then returns control to here
With Application
.ScreenUpdating = True
.Run "'Test CW.xlsm'!ThisWorkbook.TestStart" 'Uses ThisWorkbook.TestSTart as TestStart is a Workbook-level subroutine in the ThisWorkbook module
End With
ThisWorkbook.Activate
Exit Sub
CWFileError:
MsgBox "Your SVEDash application file named Test CW is not in this folder." _
& vbCrLf _
& "Please locate your current SVEDash application file and place it in this folder." _
& vbCrLf _
& "This file will close to prevent damage to your data."
On Error GoTo 0
ThisWorkbook.Close
End Sub
Any ideas on how I can bypass this security issue without the users having to change their security settings?
This seemed to only be an issue with the first 'Updte'. As I copied newer 'updated' CW into the folder, as long as I kept the name consistent the previous trusted status of the former file with that name was remembered. Hopefully thats an actual solution

How to create an App Events object without using ThisWorkbook?

Inherited a rather large selection of spreadsheets for multiple clients.
Some of these have multiple ThisWorkbooks (e.g. ThisWorkbook, ThisWorkbook2, etc...).
Trying to put some event code check to automatically run when the workbook is opened. Either Workbook or App Events could be a solution.
The recommendation from http://www.cpearson.com/Excel/AppEvent.aspx suggests adding something like the following code to ThisWorkbook.
Private XLApp As CExcelEvents
Private Sub Workbook_Open()
Set XLApp = New CExcelEvents
End Sub
The issue is that if there are multiple ThisWorkbooks, the code never runs.
Actually, testing shows if I put it into ThisWorkbook1, it runs from there. LOL.
Main Question: Is there an event to create an Application Events object that doesn't use ThisWorkbook when opening a spreadsheet?
Basically another "code gate" that is always guaranteed to run that doesn't require ThisWorkbook.
I suspect "No", but any confirmation or alternative would be helpful.
Thanks.
The Workbook.Open event is the modern way to get code to run on open.
The legacy way is to have a specially named macro in a standard module:
Public Sub Auto_Open()
MsgBox "Works!"
End Sub
That should pop the message box on open.
As mentioned in the comments, a sane Excel file only has a single Workbook module - there being more than one means the file is corrupted in some way, and that can't be good. I'd recommend rebuilding the broken files: you never know when a corrupted file will just outright crash Excel for no apparent reason.
Don't know why the corruption is happening, but it's happening enough across various spreadsheets to be worrisome.
Created code to test for a bad ThisWorkbook upon opening and not allow saving if ThisWorkbook is bad.
1 regular module (modAutoOpenAndClose) and 1 class module (classWBEvents).
Putting these 2 modules into all spreadsheets as standard procedure. As mentioned above in the comments, users will then follow the instructions from Excel Experts Tips to Fix Corrupt Spreadsheet.
Hopefully these are useful to anyone else experiencing/preventing corruption. May seem like overkill, but this has been a bedeviling issue.
Option Explicit
'modAutoOpenAndClose
Dim WorkbookEvents As classWBEvents
Function ErrorIsThisWorkBookBad() As Boolean
On Error GoTo ErrLabel
ErrorIsThisWorkBookBad = Not (ThisWorkbook.CodeName = "ThisWorkbook")
Exit Function
ErrLabel:
ErrorIsThisWorkBookBad = True
End Function
Private Sub Auto_Open()
If ErrorIsThisWorkBookBad Then
Call MsgBox("This Spreadsheet is Corrupt." + vbCrLf + vbCrLf + _
"Please Copy Tabs And Modules to New Spreadsheet." + vbCrLf + vbCrLf + _
"Saving will not be allowed.", vbCritical)
End If
Set WorkbookEvents = New classWBEvents
Set WorkbookEvents.WB = ActiveWorkbook
If Not WorkbookEvents.WB Is Nothing Then
WorkbookEvents.WB_Open
End If
End Sub
Private Sub Auto_Close()
If Not WorkbookEvents Is Nothing Then
If Not WorkbookEvents.WB Is Nothing Then
Set WorkbookEvents.WB = Nothing
End If
Set WorkbookEvents = Nothing
End If
End Sub
And
Option Explicit
'classWBEvents
Public WithEvents WB As Workbook
Private Sub WB_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If ErrorIsThisWorkBookBad Then
Call MsgBox("This Spreadsheet is Corrupt." + vbCrLf + vbCrLf + _
"Please Copy Tabs And Modules to New Spreadsheet." + vbCrLf + vbCrLf + _
"Saving will not be allowed.", vbCritical)
Cancel = True
End If
End Sub
Public Sub WB_Open()
'Reserved for project specific code
End Sub

Simple Error handling in Excel VBA

I need a simple error handling code for my small macro, I have search the web but have nothing simple, seems to be all very complicated.
I down load sales reports in .txt form on a weekly basis, I run separate macro to do stuff and then add to a master page. Not every week do sales reports download as there may not have been sales for that particular region.
I need a simple error handler so that if it does not find the report, it moves to the next sub.
Any help appreciated
Sub MXM_POS()
Workbooks.OpenText Filename:="C:\Users\903270\Documents\Excel\MXMPOS*.txt"
‘Run macro code
Run ("DLK_POS")
End Sub
Here is a simple basic structure that you can expand on as needed:
Sub MXM_POS()
On Error GoTo ErrHandler
' code here
ExitSub:
' shutdown code here
Exit Sub
ErrHandler:
If Err.Number <> 0 Then
Dim mbr As VbMsgBoxResult
mbr = MsgBox( _
"Error #" & Err.Number & ": " & Err.Description & vbNewLine & _
"Would you like to continue?", vbExclamation Or vbYesNo)
If mbr = vbYes Then Resume ExitSub
Application.Quit
End If
End Sub
When I desire a stack dump I construct that within the Source property of the Err object using concatenation with a newline, and then only display the MsgBox result at the top of the calling stack, usually either the Event Handler that launched the code or the top-level macro invoked by the user.

Add in installed and referenced

I want to check if addin is installed and is referenced. The below code checks for add in is installed or not. How can i check if its referenced in excel.
By Refernced i mean is Tools > Addins > Addins Dailog box > If addins is installed > check if a addin with particular name is checked.
I would like preferably without any loop.
Sub Demo()
Dim b As Boolean
b = CheckAddin("Solver add-in")
MsgBox "Solver is " & IIf(b, "", "not ") & "installed"
End Sub
Function CheckAddin(s As String) As Boolean
Dim x As Variant
On Error Resume Next
x = AddIns(s).Installed
On Error Goto 0
If IsEmpty(x) Then
CheckAddin = False
Else
CheckAddin = True
End If
End Function
Sub Sample()
Dim wbAddin As Workbook
On Error Resume Next
Set wbAddin = Workbooks(AddIns("My Addin").Name)
If Err.Number <> 0 Then
On Error GoTo 0
'Set wbAddin = Workbooks.Open(AddIns("My Addin").FullName)
Debug.Print "Not Referenced"
Else
Debug.Print "Referenced"
End If
End Sub
You need to test is the addin is open, pretty much like any other workbood. This will return True if an addin is loaded:
Function AddinIsLoaded(AddinName As String) As Boolean
On Error Resume Next
AddinIsLoaded = Len(Workbooks(AddIns(AddinName).Name).Name) > 0
End Function
For example:
Sub Test
Debug.Print AddinIsLoaded("Solver add-in")
End Sub
I've had a problem that even when the function returns True, I would still get an error when trying to use that addin. It turns out, an addin can be installed, but not "open". So, in addition to checking for the addin, I also check if the addin file is open. If not, I open the addin. See my question and answer here:
Excel VBA Checking if Addin Is Installed But Not Open

Saving an xlam file in the add-ins' directory

I've a xl add-in (.xlam file) which uses one of it's sheets to store data gathered from a UserForm.
If Excel closes then I'd like this file to save itself in the add-ins directory.
Currently here:
C:\Users\myName\AppData\Roaming\Microsoft\AddIns\ExcelStartUp_ExcelVersion.xlam
In the addin's before close event I've the following:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Save
End Sub
Looks ok but it saves a copy of the xlam into whatever the CurDir is. So it is reproducing iself around our file system!
If I'm in one of the code windows of the xlam file and open the Immediate window then the following two lines are inconsistent!:
?ThisWorkbook.Path
?Thisworkbook.fullname
I have been encountering the same problem and found that it is caused by the addin changing its ReadOnly status to True under certain circumstances (cannot pinpoint exactly under which circumstances but seems to be linked to having multiple instances of Excel open).
Therefore, the solution is to add a check to your code as follows:
If ThisWorkbook.ReadOnly = False Then
ThisWorkbook.Save
End If
I've had this behavior - addins being saved here and there - when more than one instance of Excel is open. (I was actually just googling it last night, but couldn't find anything confirming it.) I've got a function called from the BeforeClose event that checks for more than one instance.
Private Sub App_WorkbookBeforeClose(Cancel As Boolean)
If Not ThisWorkbook.Saved Then
If MsgBox(ThisWorkbook.Name & " Addin" & vbCrLf & "is unsaved. Save?", _
vbExclamation + vbYesNo, "Unsaved Addin") = vbYes Then
If ExcelInstanceCount > 1 Then
MsgBox "More than one Excel instance running." & vbCrLf & _
"Save cancelled", _
vbInformation, "Sorry"
Exit Sub
Else
ThisWorkbook.Save
End If
End If
End If
End Sub
Function GetExcelInstanceCount() As Long
Dim hwnd As Long
Dim i As Long
Do
hwnd = FindWindowEx(0&, hwnd, "XLMAIN", vbNullString)
i = i + 1
Loop Until hwnd = 0
GetExcelInstanceCount = i - 1
End Function
use the Application object's ActiveWorkbook.Save method instead of its ThisWorkbook.Save method. See this link: http://www.techrepublic.com/blog/microsoft-office/avoid-this-potential-gotcha-when-using-add-ins-to-distribute-excel-macros/

Resources