Doc Publishing in 4.5.1
Posted: Fri Apr 29, 2016 9:42 am
After upgrading to 4.1, our document publishing print handler has stopped working. We have a C# module, shown below, that in turn calls a vb module. The C# code is shown below:
protected override PrintJobHandlerResult OnProcess(IPrintJob printJob)
{
try
{
ERprjSendPrintJob2Svo.ERclsSendPrintJob2Svo send2Svo = new ERprjSendPrintJob2Svo.ERclsSendPrintJob2Svo();
MemoryStream destination = new MemoryStream();
var sps = ServiceContext.GetService<SelectServer>();
var username = sps.AuthenticatedUserName;
if (printJob.Properties["MergeKind"].ToString() == "All")
{
// merge the documents yourself
IPdfToolsProvider provider = GetService<IPdfToolsProvider>();
Stream merged = provider.Merge(printJob.OriginalItems
.Select(item => new MemoryStream((byte[])item.Properties["Binary"]))
.ToArray());
merged.CopyTo(destination);
}
send2Svo.ProcessPrintJob(ref printJob, username, destination.ToArray());
destination.Close();
destination.Dispose();
}
catch (Exception ex)
{
// Write this error to the Windows event Application log
EventLog.WriteEntry(sourceName, ex.Message, EventLogEntryType.Error );
}
if (debugLog == "1")
{
// Write this error to the Windows event Application log
EventLog.WriteEntry(sourceName, "end print", EventLogEntryType.Information);
}
// Proceed to next handler
return PrintJobHandlerResult.Continue;
}
A snippet of the vb code follows:
Public Class ERclsSendPrintJob2Svo
Public Sub ProcessPrintJob(ByRef printJob As IPrintJob, ByVal userName As String, ByVal bytBinaryDoc As Byte())
.
.
.
For Each objItem In printJob.OriginalItems
strFileName = objItem.Properties("Document").Title
Call SendTarget2SvoDocs( _
strFileName, _
strFullPathAndName, _
strSoftProUser, _
strSoftProOffice, _
strOrderID, _
frmQuickPost.gintParentID, _
frmQuickPost.gintDocumentType_ID, _
frmQuickPost.gstrComment, _
objItem.Properties("Binary"))
Next
'
'
'
For Example:
I select multiple documents to publish, choose to merge them, and break on the C# 'if' statement that checks 'MergeKind'. In the debugger I can see the following:
?printJob.Properties["MergeKind"].ToString()
"All"
?printJob.OriginalItems.Select(item => new MemoryStream((byte[])item.Properties["Binary"])).ToArray()
{System.IO.MemoryStream[2]}
[0]: {System.IO.MemoryStream}
[1]: {System.IO.MemoryStream}
But if I choose not to merge them, I get the following:
?printJob.Properties["MergeKind"].ToString()
"None"
?printJob.OriginalItems.Select(item => new MemoryStream((byte[])item.Properties["Binary"])).ToArray()
'printJob.OriginalItems.Select(item => new MemoryStream((byte[])item.Properties["Binary"])).ToArray()' threw an exception of type 'System.ObjectDisposedException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146232798
HelpLink: null
InnerException: null
Message: "Cannot access a closed Stream."
ObjectName: ""
Source: "mscorlib"
StackTrace: " at System.IO.__Error.StreamIsClosed()\r\n at System.IO.MemoryStream.set_Position(Int64 value)\r\n at SoftPro.Select.Shell.Printing.PrintJobItem.PropertyBag.GetBinaryValue()\r\n at SoftPro.Select.Shell.Printing.PrintJobItem.PropertyBag.get_Item(String key)\r\n at <>x.<>c.<<>m0>b__0_0(IPrintJobItem item)\r\n at System.Func`2[[SoftPro.Select.Shell.Printing.IPrintJobItem, SoftPro.Select.Shell, Version=4.1.0.0, Culture=neutral, PublicKeyToken=3834c39820615aaf],[System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Invoke(IPrintJobItem arg)\r\n at System.Linq.Enumerable.WhereSelectListIterator`2[[SoftPro.Select.Shell.Printing.IPrintJobItem, SoftPro.Select.Shell, Version=4.1.0.0, Culture=neutral, PublicKeyToken=3834c39820615aaf],[System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].MoveNext()\r\n at System.Linq.Buffer`1[[System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]]..ctor(IEnumerable`1 source)\r\n at System.Linq.Enumerable.ToArray[MemoryStream](IEnumerable`1 source)\r\n at <>x.<>m0(ERclsjPrintJobHandler <>4__this, IPrintJob printJob)"
TargetSite: {Void StreamIsClosed()}
In this second case, if I break on the Call statement in the VB code, I see the following in the debugger:
?objItem.Properties("Document").Title
"Name Affidavit (Buyer)"
?objItem.Properties("Binary")
'objItem.Properties("Binary")' threw an exception of type 'System.ObjectDisposedException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146232798
HelpLink: Nothing
InnerException: Nothing
Message: "Cannot access a closed Stream."
ObjectName: ""
Source: "Microsoft.VisualBasic"
StackTrace: " at Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)" & vbCrLf & " at Microsoft.VisualBasic.CompilerServices.NewLateBinding.CallMethod(Container BaseReference, String MethodName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, BindingFlags InvocationFlags, Boolean ReportErrors, ResolutionFailure& Failure)" & vbCrLf & " at Microsoft.VisualBasic.CompilerServices.NewLateBinding.InternalLateIndexGet(Object Instance, Object[] Arguments, String[] ArgumentNames, Boolean ReportErrors, ResolutionFailure& Failure, Boolean[] CopyBack)" & vbCrLf & " at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)" & vbCrLf & " at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type,
String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)"
TargetSite: {System.Object InvokeMethod(Method, System.Object[], Boolean[], System.Reflection.BindingFlags)}
So it appears at present that we can only distribute documents if multiple documents are selected, and the merge option is set to 'All'.
None of this code has changed, I am simply recompiling it with VS2015 and framework 4.6 to support 4.1.
Can you provide any clues as to what is going on?
protected override PrintJobHandlerResult OnProcess(IPrintJob printJob)
{
try
{
ERprjSendPrintJob2Svo.ERclsSendPrintJob2Svo send2Svo = new ERprjSendPrintJob2Svo.ERclsSendPrintJob2Svo();
MemoryStream destination = new MemoryStream();
var sps = ServiceContext.GetService<SelectServer>();
var username = sps.AuthenticatedUserName;
if (printJob.Properties["MergeKind"].ToString() == "All")
{
// merge the documents yourself
IPdfToolsProvider provider = GetService<IPdfToolsProvider>();
Stream merged = provider.Merge(printJob.OriginalItems
.Select(item => new MemoryStream((byte[])item.Properties["Binary"]))
.ToArray());
merged.CopyTo(destination);
}
send2Svo.ProcessPrintJob(ref printJob, username, destination.ToArray());
destination.Close();
destination.Dispose();
}
catch (Exception ex)
{
// Write this error to the Windows event Application log
EventLog.WriteEntry(sourceName, ex.Message, EventLogEntryType.Error );
}
if (debugLog == "1")
{
// Write this error to the Windows event Application log
EventLog.WriteEntry(sourceName, "end print", EventLogEntryType.Information);
}
// Proceed to next handler
return PrintJobHandlerResult.Continue;
}
A snippet of the vb code follows:
Public Class ERclsSendPrintJob2Svo
Public Sub ProcessPrintJob(ByRef printJob As IPrintJob, ByVal userName As String, ByVal bytBinaryDoc As Byte())
.
.
.
For Each objItem In printJob.OriginalItems
strFileName = objItem.Properties("Document").Title
Call SendTarget2SvoDocs( _
strFileName, _
strFullPathAndName, _
strSoftProUser, _
strSoftProOffice, _
strOrderID, _
frmQuickPost.gintParentID, _
frmQuickPost.gintDocumentType_ID, _
frmQuickPost.gstrComment, _
objItem.Properties("Binary"))
Next
'
'
'
For Example:
I select multiple documents to publish, choose to merge them, and break on the C# 'if' statement that checks 'MergeKind'. In the debugger I can see the following:
?printJob.Properties["MergeKind"].ToString()
"All"
?printJob.OriginalItems.Select(item => new MemoryStream((byte[])item.Properties["Binary"])).ToArray()
{System.IO.MemoryStream[2]}
[0]: {System.IO.MemoryStream}
[1]: {System.IO.MemoryStream}
But if I choose not to merge them, I get the following:
?printJob.Properties["MergeKind"].ToString()
"None"
?printJob.OriginalItems.Select(item => new MemoryStream((byte[])item.Properties["Binary"])).ToArray()
'printJob.OriginalItems.Select(item => new MemoryStream((byte[])item.Properties["Binary"])).ToArray()' threw an exception of type 'System.ObjectDisposedException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146232798
HelpLink: null
InnerException: null
Message: "Cannot access a closed Stream."
ObjectName: ""
Source: "mscorlib"
StackTrace: " at System.IO.__Error.StreamIsClosed()\r\n at System.IO.MemoryStream.set_Position(Int64 value)\r\n at SoftPro.Select.Shell.Printing.PrintJobItem.PropertyBag.GetBinaryValue()\r\n at SoftPro.Select.Shell.Printing.PrintJobItem.PropertyBag.get_Item(String key)\r\n at <>x.<>c.<<>m0>b__0_0(IPrintJobItem item)\r\n at System.Func`2[[SoftPro.Select.Shell.Printing.IPrintJobItem, SoftPro.Select.Shell, Version=4.1.0.0, Culture=neutral, PublicKeyToken=3834c39820615aaf],[System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Invoke(IPrintJobItem arg)\r\n at System.Linq.Enumerable.WhereSelectListIterator`2[[SoftPro.Select.Shell.Printing.IPrintJobItem, SoftPro.Select.Shell, Version=4.1.0.0, Culture=neutral, PublicKeyToken=3834c39820615aaf],[System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].MoveNext()\r\n at System.Linq.Buffer`1[[System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]]..ctor(IEnumerable`1 source)\r\n at System.Linq.Enumerable.ToArray[MemoryStream](IEnumerable`1 source)\r\n at <>x.<>m0(ERclsjPrintJobHandler <>4__this, IPrintJob printJob)"
TargetSite: {Void StreamIsClosed()}
In this second case, if I break on the Call statement in the VB code, I see the following in the debugger:
?objItem.Properties("Document").Title
"Name Affidavit (Buyer)"
?objItem.Properties("Binary")
'objItem.Properties("Binary")' threw an exception of type 'System.ObjectDisposedException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146232798
HelpLink: Nothing
InnerException: Nothing
Message: "Cannot access a closed Stream."
ObjectName: ""
Source: "Microsoft.VisualBasic"
StackTrace: " at Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)" & vbCrLf & " at Microsoft.VisualBasic.CompilerServices.NewLateBinding.CallMethod(Container BaseReference, String MethodName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, BindingFlags InvocationFlags, Boolean ReportErrors, ResolutionFailure& Failure)" & vbCrLf & " at Microsoft.VisualBasic.CompilerServices.NewLateBinding.InternalLateIndexGet(Object Instance, Object[] Arguments, String[] ArgumentNames, Boolean ReportErrors, ResolutionFailure& Failure, Boolean[] CopyBack)" & vbCrLf & " at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)" & vbCrLf & " at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type,
String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)"
TargetSite: {System.Object InvokeMethod(Method, System.Object[], Boolean[], System.Reflection.BindingFlags)}
So it appears at present that we can only distribute documents if multiple documents are selected, and the merge option is set to 'All'.
None of this code has changed, I am simply recompiling it with VS2015 and framework 4.6 to support 4.1.
Can you provide any clues as to what is going on?