Crash when using SafeMailItem (fault in mso20win32client.dll) - outlook

We use Redemption since many years. Since few days many of our clients have issues when they use our plugin for Outlook. We changed nothing in our app.
I did some traces and found that the line Set CourielOutlook = New Redemption.SafeMailItem makes the app to crash. Events viewer show that the fault is in mso20win32client.dll.
I tried to find the problem by create a simple app doing the same thing and there is no problem with this one!!?
I found that if I rename the original app with a new name (AddinOutlook.exe to AddinOutlook2.exe), the app doesn't crash anymore!
If I rename my simple app to AddinOutlook.exe, it crashes!
I tried many things in Outlook (deleting and recreating the profile, deleting and recreating the account, uninstall and reinstall Office 365). The problem still there.
After deleting and recreating the profile, it works the first time, but after that never (except if I rename the exe).
Any idea?
Here is my simple test app:
Dim Outlook As Outlook.Application
Dim Item As Object
Dim Namespace As Object
Dim CourielOutlook As Object 'Redemption.SafeMailItem
Set Outlook = New Outlook.Application
If Not Outlook Is Nothing Then
On Error Resume Next
Err.Clear
Set Namespace = Outlook.GetNamespace("MAPI")
If Err.Number <> 0 Then
Call Namespace.Logon(vbNullString, vbNullString, False)
End If
If Err.Number = 0 Then
If TypeName(Outlook.ActiveWindow) = "Inspector" Then
Call AjouterElement(Outlook.ActiveInspector.CurrentItem)
Set CourielOutlook = New Redemption.SafeMailItem
CourielOutlook.Item = Outlook.ActiveInspector.CurrentItem
'...
ElseIf TypeName(Outlook.ActiveWindow) = "Explorer" Then
For Each Item In Outlook.ActiveExplorer.Selection
Set CourielOutlook = New Redemption.SafeMailItem
CourielOutlook.Item = Item
'...
Next
End If
End If
End If
Set Outlook = Nothing

Related

How can I detect an unmanaged C++ project in a visual studio extension

In my Visual Studio Extension, I need to detect whether a C++ project is managed or unmanaged code.
Previously, I had a satisfactory method, described in this posting in an MSDN forum.
In that example, it was necessary to get the ManagedExtensions property of the active configuration.
Sub Macro1()
Dim objProject As EnvDTE.Project
Dim objConfiguration As EnvDTE.Configuration
Dim objProperty As EnvDTE.Property
For Each objProject In DTE.Solution.Projects
objConfiguration = objProject.ConfigurationManager.ActiveConfiguration()
objProperty = objConfiguration.Properties.Item("ManagedExtensions")
System.Windows.Forms.MessageBox.Show(objProject.Name & " (" & objConfiguration.ConfigurationName & ") ManagedExtensions: " & objProperty.Value.ToString)
Next
End Sub
Unfortunately, this method is no longer working for me.
For unmanaged projects, I get an exception trying to fetch the ActiveConfiguration.
For managed projects, I can get the ActiveConfiguration, but the ManagedExtensions property is not available. In fact, I think that the properties collection is empty.
Is there a new way to recognize an unmanaged C++ project?
You can get the ManagedExtensions property via the VCConfiguration object, with code something like
Private Enum compileAsManagedOptions
managedNotSet = 0
managedAssembly = 1
managedAssemblyPure = 2
managedAssemblySafe = 3
managedAssemblyOldSyntax = 4
End Enum
Dim VCProj As Object 'VCProject
Dim VCConfig As Object 'VCConfiguration
Dim VCManagedOption As compileAsManagedOptions = compileAsManagedOptions.managedAssemblyPure
VCProj = prj.Object
If VCProj IsNot Nothing Then
VCConfig = VCProj.Configurations.Item(1)
If VCConfig IsNot Nothing Then
VCManagedOption = VCConfig.ManagedExtensions
End If
End If
where prj is the Envdte.Project object.
This code is only executed if I already know that it is a C++ project, based on the project kind.
I defined the variables as object, so that I don't have to add a reference to
Microsoft.VisualStudio.VCProject.dll
to my package, because this DLL will only be present if support for C++ projects has been installed.

referencing WinSCP COM library from VB6

I am trying to use the WinSCP COM library on a old VB6 project I have (it's a legacy application that generates an OCX file, I think we have to use VB6 for it but not 100% sure).
Anyway we want to implement SFTP, and WinSCP can do that readily.
I registered the COM object, and can see the WinSCPNet type library when I go to add the reference. However I can't see the properties/methods of the classes when I look at the library in the object browser. Further, this code fails, it does not get to the 3rd MsgBox ("In SendWinSCP4"), it returns from the function at that point, I think because the property UserName is not exposed.
MsgBox ("in SendWinSCP")
Dim session As WinSCPnet.session
Dim sessionOptions As WinSCPnet.sessionOptions
Dim transferOptions As WinSCPnet.transferOptions
Set session = New WinSCPnet.session
Set sessionOptions = New WinSCPnet.sessionOptions
Set transferOptions = New WinSCPnet.transferOptions
MsgBox ("in SendWinSCP3")
sessionOptions.Protocol = Protocol_Sftp
sessionOptions.HostName = "example.com"
sessionOptions.UserName = "user"
sessionOptions.Password = "example.com"
sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
MsgBox ("in SendWinSCP4 " & sessionOptions.HostName & "!")
See above, using On Error Resume Next got me past the error.

Get list of ALM project AND domains names in VBScript (QC11 OTA)

I am trying to list QC11 project and domain name in combo box on form load() but I am getting error object required,code I am using:
Dim tdc As New TDAPIOLELib.TDConnection
Dim projectList As Customization
Dim Project As Customization
Dim Domain As Customization
Set tdc = CreateObject("TDApiOle80.TDConnection")
tdc.InitConnectionEx "https://xyz/omu"
For Each Domain In TheTDConnection.DomainsList
Set projectList = tdc.GetAllVisibleProjectDescriptors
For Each Project In projectList
ComboBox1.AddItem (Project.Name)
ComboBox2.AddItem (Project.DomainName)
Next Project
Next Domain
If that's really the code you are using, then for a start this line is probably generating an error:
For Each Domain In TheTDConnection.DomainsList
Based on the rest of your code "TheTDConnection" should be "tdc":
For Each Domain In tdc.DomainsList
Oh, and to be doing this you should almost certainly be logged in first by calling tdc.Login... rather than just connected to the server.
On a related note, the DomainsList property is deprecated. I think you can just loop through the List of ProjectDescriptor objects returned by GetAllVisibleProjectDescriptors since that covers all projects under all domains that the current logged on user has access to.
Edit: this is a complete solution based on the original question. Here's working tested code that will cycle through the domains/projects that the provided user has access to. This assumes you have the QC/ALM Connectivity add-in installed (required).
If you are running this piece of VBScript on a 64 bit machine you need to run it using the 32bit version of wscript.exe: C:\Windows\SysWOW64\wscript.exe "c:\somewhere\myscript.vbs"
msgbox "Creating connection object"
Dim tdc
Set tdc = CreateObject("TDApiOle80.TDConnection")
msgbox "Connecting to QC/ALM"
tdc.InitConnectionEx "http://<yourServer>/qcbin/"
msgbox "Logging in"
tdc.Login "<username>", "<password>"
Dim projDesc
msgbox "Getting project descriptors"
Set projectDescriptors = tdc.GetAllVisibleProjectDescriptors
For Each desc In projectDescriptors
msgbox desc.DomainName & "\" & desc.Name
Next
msgbox "Logging out"
tdc.Logout
msgbox "Disconnecting"
tdc.Disconnect
msgbox "Releasing connection"
tdc.ReleaseConnection
Edit 2:
If you want to parse the resulting XML from sa.GetAllDomains into a list of ALL domain\project items on the server you can do this (This is VBScript since the original question & tag still mention it, and has been tested):
Set objDoc = CreateObject("MSXML.DOMDocument")
objDoc.Load "C:\yourXmlFile.xml"
Set objRoot = objDoc.documentElement
For Each domain in objRoot.selectNodes("TDXItem")
For Each project in domain.selectNodes("PROJECTS_LIST/TDXItem")
msgbox domain.selectSingleNode("DOMAIN_NAME").text & "\" & project.selectSingleNode("PROJECT_NAME").text
Next
Next

vb script simulate keystroke when not logged in

I really don't know much about VB script, and I could use some help with this little problem.
I'm trying send an email once a certain script is run every morning (a scheduled task). Now, our email server is configured to prevent sending automated emails - a feature I generally appreciate - and so I need to simulate a keystroke to acknowledge a warning box and actually send the email.
Here's the script I have so far:
Sub SendEmail_Outlook()
Set WshShell = WScript.CreateObject("WScript.Shell")
Set ol=CreateObject("Outlook.Application")
Set Mail=ol.CreateItem(0)
Mail.to= "X#xyz.com"
Mail.Subject = "Subject"
Mail.HTMLBody = "Body"
Mail.Display
WScript.Sleep 1000
WshShell.SendKeys "%s"
Set Mail = Nothing
Set ol = Nothing
End Sub
SendEmail_Outlook
The script works like a charm, but only if I'm logged in. If I'm not logged in, the email draft is prepared, the window is activated, but the email is not actually sent. I'm assuming it's because the simulated keystroke does not work if no one's logged in?
So, the question is: is there a way to "tweak" this script to make it run even when no one's logged in?
Many thanks, help would be appreciated!
Philipp
Did you check the vbscript [info] section? It explains how cscript.exe can execute vbscript while the user is not logged on.
"Note: Scheduled VBScript tasks succeed under Cscript.exe due to running the script as a console application rather than a windows application. Computer/Domain policies limit activation of windows applications while no user is logged on."
Edit:
Activate the sending of email over the .Send property rather than using the sendkeys method.
Sub SendEmail_Outlook()
Set WshShell = WScript.CreateObject("WScript.Shell")
Set ol=CreateObject("Outlook.Application")
Set Mail=ol.CreateItem(0)
Mail.to= "X#xyz.com"
Mail.Subject = "Subject"
Mail.HTMLBody = "Body"
Mail.Display
WScript.Sleep 1000
'-----------
Mail.Send
'-----------
Set Mail = Nothing
Set ol = Nothing
End Sub
SendEmail_Outlook
Further information on automating emails directly too the outlook application can be referenced here: Link
With the help of a colleague, I think I found the answer - at least it's an option I've implemented and it seems to run successfully so far. As this may be of interest to others as well, there's what we have done:
Download and install "Outlook Redemption" here: http://www.dimastr.com/redemption/home.htm. No admin rights required.
Use the following script:
Sub SendEmail_Outlook()
Set WshShell = WScript.CreateObject("WScript.Shell")
Set oApp=CreateObject("Outlook.Application")
Set NS = oApp.GetNamespace("MAPI")
NS.Logon
Set SafeItem = CreateObject("Redemption.SafeMailItem")
Set oMailItem = oApp.CreateItem(0)
SafeItem.Item = oMailItem
SafeItem.To = "x#yz.com"
SafeItem.Subject = "Subject"
SafeItem.BodyFormat = 2
SafeItem.HTMLBody = "Body"
SafeItem.Send
SafeItem = Nothing
Set oMailItem = Nothing
Set NS = Nothing
Set oApp = Nothing
End Sub
SendEmail_Outlook
As indicated, the script has been running smoothly, despite getting an error at the end, saying that:
VBScript runtime error: Object variable not set: 'SafeItem'
But, the email arrives, so the error doesn't really bother me... ;-)

"Method or Data Member Not Found" When Trying to Execute Database Code

I have a test project I'm using to familiarise myself with VB6. Just a listbox, a button to get info, and a button to clear info:
Code:
Option Explicit
Private Sub btnGet_Click()
lstResults.DataSource = GetMenuItems
End Sub
Private Sub btnClear_Click()
lstResults.Clear
End Sub
Public Function GetMenuItems() As ADODB.Recordset
Dim rs As ADODB.Recordset
Dim conn As New ADODB.Connection
conn.ConnectionString = "File Name=C:\connString.udl"
Dim cmd As New ADODB.Command
Set cmd.ActiveConnection = conn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "dbo.GetMenuItems"
Set rs = cmd.Execute()
GetMenuItems = rs
End Function
The following error appears when I click the Get Items button (btnGet):
Compile Error: Method or Data Member Not Found
At first I thought it might be something to do with the event/button, that some sort of binding between them wasn't present. But just putting in something like "MsgBox("Hello")" works fine. Yet it doesn't even seems to get to the line where the GetMenuItems function is called before throwing the error.
This being my first whirl with VB, I'm a little stumped.
EDIT - I've had a look at the UDL file I was using too. Tested that and its connecting ok on its own.
In Sub btnGet_Click, use
Set lstResults.DataSource = GetMenuItems
Assigning object references without using Set is hardly ever the right thing to do. For what it's worth, omitting Set references the left-hand side's default property; this was part of VB6 (OK, VB4, when classes were introduced) as a help to VB3 programmers, before there were such things as objects. Whatever kind of object lstResults.DataSource returns likely does not have a default property, leading to the "Method or data member not found" error.
You've got a private sub btnGet_Click() calling a public function GetMenuItems(), which may cause problems.
Also I'm not sure you can use a udl as the connection string. Instead, open the UDL (you may need to change the file extension to .txt temporarily), take the connection string out, and use that in place of the file name.
Also, check the stored procedure exists dbo.GetMenuItems

Resources