Suppressing Visio.Application alerts - vbscript

I have a VBScript that opens a Visio file in the background by using Visio.Application in invisible mode.
Set Visioapp = CreateObject("Visio.Application")
Visioapp.Visible = False
Set Visio = Visioapp.Documents.Open(VisioFile)
This works fine except when I try to open a file that generates a pop-up while I'm processing it. If that happens, the application would show an alert to notify the user but since the application is invisible to the user (or running without a user present), the script just hangs indefinitely, waiting for input that won't be coming.
If I were writing VBA code for Excel or Word I could use Application.DisplayAlerts = False (and/or possibly DisplayEvents). But in my VBScript the Visio application doesn't have that property. Visioapp.DisplayAlerts = False will give me the error "Object doesn't support this property or method".
How do I suppress the popups generated by a Visio application opened from VBScript?

Summarizing the comments from #Dave and #Noodles, the Visio Application object does not have a property DisplayAlerts like other Office applications have. Instead it provides a property AlertResponse that allows you to define whether the application should respond to alerts with OK, Cancel, Abort, Retry, …
To have the application respond with OK to all alerts change your code to something like this:
Set Visioapp = CreateObject("Visio.Application")
visioapp.AlertResponse = vbOk
Set Visio = Visioapp.Documents.Open(VisioFile)
Note that in this case you can use the symbolic constants that VBScript already provides (vbOk, vbCancel, vbAbort, vbRetry, …). For application-specific constants (e.g. the SaveFlags for the SaveAsEx method) this won't work, though. In those cases you'll have to either use the numeric value:
Visio.SaveAsEx "C:\path\to\output.vsd", 1
or define the constant in your script:
Const visSaveAsRO = 1
...
Visio.SaveAsEx "C:\path\to\output.vsd", visSaveAsRO

Related

How to get rid of prompt on quitting MS ACCESS

I am running a Sub procedure stored in an ACCESS database using VBScript. The procedure queries the database and exports/saves a CSV file.
My problem is that the script successfully opens the database, runs the procedure but then leaves ACCESS open because ACCESS opens a prompt asking "Are you sure that you want to leave ACCESS" (rather its equivalent in German). I want it to close without interaction.
The basic idea of this script is to run it via the Windows Task Scheduler. (Which does not work right now but that is another question.)
Here is the part of my VBScript dealing with the ACCESS database:
Dim objAccess
Set objAccess = createObject("Access.Application")
objAccess.OpenCurrentDataBase("C:\FiselTools\Allgemein\Scripte\Pellenc-CopyBelegarchiv3.accdb")
objAccess.Run "CopyBelegarchiv"
objAccess.Quit acQuitSaveAll
Set objAccess = Nothing
Using this script manually, it does open the database, export the file, finally executes the part following the code from above - so only closing ACCESS does not work and my guess is that it's not a problem with the script or the procedure but the ACCESS.
Erik A basically gave the right answer: there was some VBA code that is responsible for this prompt (see below). It was part of the primary form.
So in this case I found two possible solutions:
Do not display/show the form (which worked for me as I made a copy of the file dedicated for just this purpose).
If you need the form then you might need to delete the VBA code.
Private Sub Form_Unload(Cancel As Integer)
Dim Answer As Variant
Answer = MsgBox("Wollen Sie die Anwendung wirklich beenden?" & vbNewLine & vbNewLine & "Nicht gespeicherte Änderungen gehen dabei möglicherweise verloren", vbQuestion + vbYesNo + vbDefaultButton2)
If Answer = vbNo Then
Cancel = True
Else
DoCmd.Quit acQuitSaveNone
End If
End Sub
Since it is part of the Access class object of the form that is configured to be displayed on opening the ACCESS database and I do not need the form when I run the procedure via VBScript I simply changed the database to not display any form when the database is opened.
Some day I will remove any form, query, and any other object not needed from this special copy of the database that I don't need to run from VBScript.
Thanks!

Unable to change registry on Windows 10

I'm trying to change the value of the Shell registry key on Windows 10 using the following code:
Public Function overwriteStartup()
Try
Dim winlogon As RegistryKey = My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", True)
winlogon.SetValue("AutoRestartShell", 0, RegistryValueKind.DWord)
winlogon.SetValue("Shell", Application.ExecutablePath, RegistryValueKind.String)
winlogon.Flush()
winlogon.Close()
Return True
Catch ex As Exception
Return False
End Try
End Function
The issue is that Shell and AutoRestartShell are not changing.
If I add MessageBox.Show(My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon").GetValue("Shell")) between winlogon.Close() and Return True, I get a message box that shows the correct value (which means that the value was changed), but when I check regedit, it shows the original value, so it did not actually change the value.
If your app can read the registry value - You must need to provide administrative privileges before letting your app write registry values. Go to the app manifest and set the privilege to requireAdministrator then try again, it should work.
If you remove the exception handling Try Catch, then you'll get to know the exact reason.
I changed the target framework to .NET 4 and set target CPU to AnyCPU, it works now.

Will this VBSCRIPT code trigger the message box?

I'm looking through at an old Classic ASP page that uses VBScript. The code below appears to use a variable stored in the config (global.asa) called called CODES_TIMESTAMP. However looking at the servers in question it appears that that variable no longer exists. My question is, if that variable is not defined in the config file then will the error message box be activated?
Dim DB_TIMESTAMP_CODES
DB_TIMESTAMP_CODES = "<%=Application("CODES_TIMESTAMP")%>"
If trim(DB_TIMESTAMP_CODES) = "" Then
msgbox "Setup Error... Codes are not Defined"
End If
My question is, if that variable is not defined in the config file then will the error message box be activated?
Value will be "". But msgbox cannot be executed on ASP web page. msgbox will appear only from VBS script.
The code below appears to use a variable stored in the config (global.asa) called called CODES_TIMESTAMP
You (previous developer) could assign value to Application variable from any page. I suggest you to make full search over all .ASP pages, may be this value assigned not in GLOBAL.ASA

Add item to Error List in Macro

I want to notify the user of the macro if something went wrong during the execution of the macro. I was wondering if it would be possible to add an item to the Visual Studio error list?
It is possible to do so from within an AddIn (like here), but I would like to do the same thing from a macro.
Edit
To further clarify what i want to achive, here is the sample from the Samples macro library (Alt+F8 -> Samples -> Utilities -> SaveView())
Sub SaveView()
Dim name As String
name = InputBox("Enter the name you want to save as:", "Save window layout")
If (name = "") Then
MsgBox("Empty string, enter a valid name.")
Else
DTE.WindowConfigurations.Add(name)
End If
End Sub
Instead of the MsgBox("...") alert I want to put the error into the VS error list.
You can add an item in the Task List easily from your macro. Just use the AddTaskToList method from that article and change m_objDTE to DTE. I've tried it and it worked.
However, adding the item in Error List, is probably impossible. You need to call VS services, see how adding an error is done in an add-in. I created a macro from this code and it didn't work. In general, VS services don't work in macros. I was able to create ErrorListProvider successfully. I could access it's methods and properties. But calling ErrorListProvider.Task.Add caused COM exception. If you want to play with it, several notes:
As described in the article, you need to get 4 assemblies out of the GAC e.g. to c:\dlls\ directory. Since Macros IDE doesn't allow you to browse when you Add Reference, you need to copy these dlls into ...\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies directory (change the 10.0 to your VS version). Then, when you Add Reference in Macros IDE, you should see the assemblies.
The GetService function always returned Nothing. Add the following field to the class:
Private serviceProvider As IServiceProvider = New Microsoft.VisualStudio.Shell.ServiceProvider(CType(DTE, Microsoft.VisualStudio.OLE.Interop.IServiceProvider))
and in GetService function change line:
objService = Microsoft.VisualStudio.Shell.Package.GetGlobalService(serviceType)
to
objService = serviceProvider.GetService(serviceType)
As I wrote, everything seems OK then but ErrorListProvider.Task.Add fails.
I think that for your situation outputting something to your own output pane would be more suitable. The error list is generally used for errors within the project the user is working on, not for errors caused by running macros. Especially when someone says it can't be done. :)
Outputting to your own output pane is pretty easy:
DTE.Windows.Item(Constants.vsWindowKindOutput).Activate()
Dim panes As OutputWindowPanes = window.OutputWindowPanes
Dim my_pane As OutputWindowPane
Try
my_pane = panes.Item("SaveView")
Catch exception As System.ArgumentException
my_pane = panes.Add("SaveView")
End Try
my_pane.Activate()
my_pane.OutputString("Empty string, enter a valid name." + vbCrLf)
Hope this helps.
Cheers,
Sebastiaan
Is this not what you want?
HOWTO: Add an error with navigation to the Error List from a Visual Studio add-in
http://www.mztools.com/articles/2008/MZ2008022.aspx

VB6.0 : initialize method of a User Control called when loading a VB project

Whenever we load a VB project it will call Initialize event of a User Control ( if there is any in the project). My problem is that is that I have some code in UserControl_Initialize that will try to create instances of other COM objects. On my build machine those controls are not registered. One option is to move the code to some other method other than Initialize but I want to know if there is a better solution? Somewhere I found that we may have a check to see if the calling application is VB editor then skip the initialization code...
You can use:
If Not Me.DesignMode Then
...
End If
An other solution we used was a little function which can be used globally:
Public Function IsRuntime() as Boolean
On Error Goto NotRuntime
Debug.Print(1 / 0)
IsRuntime = True
Exit Function
NotRuntime:
IsRuntime = False
End If
Don't know if it is syntactically well formed, but the idea should be clear:
Only in the IDE the debug statement is called.
This only happens if your project was saved with the form designer open: this means that at startup the form is displayed (maybe in the background) and consequently, all controls on it need to be initialized. Hence, your user control initializer is called if this control is used on the form.
To prevent this, simply save the project with the form designer closed.

Resources