Search Unity

UWP Printing

Discussion in 'Windows' started by mhf, Jul 20, 2019.

  1. mhf

    mhf

    Joined:
    Nov 26, 2012
    Posts:
    4
    Hoping to get UWP print functionality in my Unity UWP app by following the steps in

    stackoverflow question 9074684 - how-to-print-in-uwp-app


    Here's the relevant parts of my app:

    Code (CSharp):
    1. #if (ENABLE_IL2CPP && UNITY_WSA_10_0)
    2.     void InitializePrinting()
    3.     {
    4.         printMan = PrintManager.GetForCurrentView();
    5.         printMan.PrintTaskRequested += PrintTaskRequested;
    6.         printDoc = new PrintDocument();
    7.         printDocSource = printDoc.DocumentSource;
    8. ......
    9.  
    10. void OnPrint()
    11. {
    12. UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
    13.             {
    14.                 InitializePrinting();
    15.             }, true);
    16.  
    17. }
    However program is hanging when new PrintDocument() is called...

    Any ideas, anyone?
     
  2. timke

    timke

    Joined:
    Nov 30, 2017
    Posts:
    408
    So, offhand I noticed your calling InvokeOnUIThread() with true for waitUntilDone parameter; this should be false.
    This is blocking the calling thread and is probably causing the deadlock
     
  3. mhf

    mhf

    Joined:
    Nov 26, 2012
    Posts:
    4
    Thanks for responding!

    I did change the parameter to false, but still seems to hang when creating the PrintDoc object. Also I'm calling the InitializePrinting() function from an OnEnable

    Code (CSharp):
    1. #if (ENABLE_IL2CPP && UNITY_WSA_10_0)
    2.     void InitializePrinting()
    3.     {
    4.         printMan = PrintManager.GetForCurrentView();
    5.         printMan.PrintTaskRequested += PrintTaskRequested;
    6.         printDoc = new PrintDocument();
    7.         printDocSource = printDoc.DocumentSource;
    8. ......
    9. void OnEnable()
    10. {
    11. UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
    12.             {
    13.                 InitializePrinting();
    14.             }, false);
    15. }
     
  4. timke

    timke

    Joined:
    Nov 30, 2017
    Posts:
    408
    I quickly tried this code out but wasn't able to repro the deadlock. So a couple additional questions:

    - Are you building a "XAML Project" for UWP?
    Since PrintDocument is a XAML control, you'll need to use the project type. I tried it with D3D and just got a RPC_E_WRONG_THREAD error (but didn't deadlock).

    - What version of Unity are you using?
    - Are you using IL2CPP or .NET back end (if on a 217.4 or older release)?
     
  5. mhf

    mhf

    Joined:
    Nov 26, 2012
    Posts:
    4
    sorry for the delay in responding..

    I switched from a D3D to a XAML project
    using Unity 2018.3.13f1
    with IL2CPP backend

    When printDoc = new PrintDocument(); is called, I'm getting an exception:

    Exception: Exception of type 'System.Exception' was thrown.
    at Windows.UI.Xaml.Printing.PrintDocument..ctor () [0x00000] in <00000000000000000000000000000000>:0
    at ScreenShotPopUp.InitializePrinting2 () [0x00000] in <00000000000000000000000000000000>:0
    at ScreenShotPopUp+<DoScreenshot>d__65.MoveNext () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00000] in <00000000000000000000000000000000>:0

    #if (ENABLE_IL2CPP && UNITY_WSA_10_0)
    void InitializePrinting()
    {
    // Printing
    LogManager.mInstance.Log("ScreenShotPopuUp.InitializePrinting");

    LogManager.mInstance.Log("ScreenShotPopuUp.InitializePrinting getting printMan");
    printMan = PrintManager.GetForCurrentView();
    LogManager.mInstance.Log("ScreenShotPopuUp.InitializePrinting adding PrintTaskRequested");
    printMan.PrintTaskRequested += PrintTaskRequested;

    LogManager.mInstance.Log("ScreenShotPopuUp.InitializePrinting Done");

    InitializePrinting2();
    }

    void InitializePrinting2()
    {
    // Build a PrintDocument and register for callbacks
    LogManager.mInstance.Log("ScreenShotPopuUp.InitializePrinting2 creating printdocument");
    printDoc = new PrintDocument();
     
  6. timke

    timke

    Joined:
    Nov 30, 2017
    Posts:
    408
    Are you calling InitializePrinting() on the UI thread? From this recent code you pasted it doesn't seem like you are, whereas in your original post you did.

    Code (CSharp):
    1.  
    2. void Start()
    3. {
    4. #if (ENABLE_IL2CPP && UNITY_WSA_10_0)
    5.  
    6. UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
    7. {
    8.     InitializePrinting();
    9. }, false);
    10. #endif
    11.  
    I tried the Printing APIs in a 2018.3 release of Unity using IL2PP (invoking them on the UI thread) and didn't hit the exception or run into other issues creating a new PrintDocument.
     
  7. mhf

    mhf

    Joined:
    Nov 26, 2012
    Posts:
    4
    Looks like I got it working. I think I was attempting to create printDoc a second time.

    Really appreciate your help.