Added initial PInvoke.Printing project with winspool.h implementations

pull/83/head
David Hall 2019-12-10 06:56:36 -07:00
parent f74d478b28
commit 945d381524
9 changed files with 13094 additions and 0 deletions

180
PInvoke/Printing/PrntvPt.cs Normal file
View File

@ -0,0 +1,180 @@
using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>Functions and structures from prntvpt.h.</summary>
public static partial class PrntvPt
{
/// <summary>
/// <para>
/// [This function is not supported and might be disabled or deleted in future versions of Windows. <c>PTOpenProviderEx</c> provides
/// equivalent functionality and should be used instead.]
/// </para>
/// <para>Opens an instance of a print ticket provider.</para>
/// </summary>
/// <param name="pszPrinterName">The full name of a print queue.</param>
/// <param name="maxVersion">The latest version of the Print Schema that the caller supports.</param>
/// <param name="prefVersion">The version of the Print Schema requested by the caller.</param>
/// <param name="phProvider">A pointer to a handle to the print ticket provider.</param>
/// <param name="usedVersion">The version of the Print Schema that the print ticket provider will use.</param>
/// <returns>
/// If the method succeeds, it returns <c>S_OK</c>; otherwise, it returns an <c>HRESULT</c> error code. For more information about
/// COM error codes, see Error Handling.
/// </returns>
/// <remarks>Before calling this function, the calling thread must initialize COM by calling <c>CoInitializeEx</c>.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/printdocs/bindptproviderthunk HRESULT BindPTProviderThunk( _In_ LPTSTR
// pszPrinterName, _In_ INT maxVersion, _In_ INT prefVersion, _Out_ HPTPROVIDER *phProvider, _Out_ INT *usedVersion );
[DllImport(Lib.PrntvPt, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("", MSDNShortId = "815cc360-8dcd-4c58-a64d-5d77436a8623")]
public static extern HRESULT BindPTProviderThunk(string pszPrinterName, int maxVersion, int prefVersion, out SafeHPTPROVIDER phProvider, out int usedVersion);
/// <summary>
/// <para>[This function is not supported and might be disabled or deleted in future versions of Windows. <c>PTGetPrintCapabilities</c> provides equivalent functionality and should be used instead.]</para>
/// <para>Retrieves the printer's capabilities formatted in compliance with the XML Print Schema.</para>
/// </summary>
/// <param name="hProvider">A handle to an open print ticket provider. This handle is returned by the <c>BindPTProviderThunk</c> function.</param>
/// <param name="pPrintTicket">The buffer that contains the print ticket data, expressed in XML as described in the Print Schema.</param>
/// <param name="cbPrintTicket">The size, in bytes, of the buffer referenced by pPrintTicket.</param>
/// <param name="ppbPrintCapabilities">The address of the buffer that is allocated by this function and contains the valid print capabilities information, encoded as XML. This function calls <c>CoTaskMemAlloc</c> to allocate this buffer. When the buffer is no longer needed, the caller must free it by calling <c>CoTaskMemFree</c>.</param>
/// <param name="pcbPrintCapabilitiesLength">The size, in bytes, of the buffer referenced by ppbPrintCapabilities.</param>
/// <param name="pbstrErrorMessage">A pointer to a string that specifies what, if anything, is invalid about pPrintTicket. If it is valid, this value is <c>NULL</c>. If pbstrErrorMessage is not <c>NULL</c> when the function returns, the caller must free the string with <c>SysFreeString</c>.</param>
/// <returns>If the method succeeds, it returns <c>S_OK</c>; otherwise, it returns an <c>HRESULT</c> error code. For more information about COM error codes, see Error Handling.</returns>
// https://docs.microsoft.com/en-us/windows/win32/printdocs/getprintcapabilitiesthunk2
// HRESULT GetPrintCapabilitiesThunk2( _In_ HPTPROVIDER hProvider, _In_ BYTE *pPrintTicket, _In_ INT cbPrintTicket, _Out_ BYTE **ppbPrintCapabilities, _Out_ INT *pcbPrintCapabilitiesLength, _Out_opt_ BSTR *pbstrErrorMessage );
[DllImport(Lib.PrntvPt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winspool.h", MSDNShortId = "15219c19-b64c-4c51-9357-15a797557693")]
public static extern HRESULT GetPrintCapabilitiesThunk2(HPTPROVIDER hProvider, [In] IntPtr pPrintTicket, int cbPrintTicket, out IntPtr ppbPrintCapabilities, out int pcbPrintCapabilitiesLength, [MarshalAs(UnmanagedType.BStr)] out string pbstrErrorMessage);
/// <summary>Closes a print ticket provider handle.</summary>
/// <param name="hProvider">A handle to the provider. This handle is returned by the PTOpenProvider or PTOpenProviderEx function.</param>
/// <returns>
/// <para>If the operation succeeds, the return value is S_OK, otherwise the <c>HRESULT</c> contains an error code.</para>
/// <para>If hProvider was opened in a different thread, the <c>HRESULT</c> is E_INVALIDARG.</para>
/// <para>For more information about COM error codes, see Error Handling.</para>
/// </returns>
/// <remarks>
/// <para>
/// <c>Note</c> This is a blocking or synchronous function and might not return immediately. How quickly this function returns
/// depends on run-time factors such as network status, print server configuration, and printer driver implementation—factors that
/// are difficult to predict when writing an application. Calling this function from a thread that manages interaction with the user
/// interface could make the application appear to be unresponsive.
/// </para>
/// <para>
/// The hProvider parameter must be a handle that was opened in the same thread as the thread in which it is used for this function.
/// </para>
/// <para>A handle cannot be used after it is closed.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/prntvpt/nf-prntvpt-ptcloseprovider HRESULT PTCloseProvider( HPTPROVIDER
// hProvider );
[DllImport(Lib.PrntvPt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("prntvpt.h", MSDNShortId = "28e85b53-fd0c-4210-ae2b-794efaf65bd4")]
public static extern HRESULT PTCloseProvider(HPTPROVIDER hProvider);
/// <summary>
/// <para>
/// [This function is not supported and might be disabled or deleted in future versions of Windows. <c>PTCloseProvider</c> provides
/// equivalent functionality and should be used instead.]
/// </para>
/// <para>Closes a handle to a print ticket provider.</para>
/// </summary>
/// <param name="hProvider">
/// A handle to an open print ticket provider. This handle is returned by the <c>BindPTProviderThunk</c> function.
/// </param>
/// <returns>
/// If the method succeeds, it returns <c>S_OK</c>; otherwise, it returns an <c>HRESULT</c> error code. For more information about
/// COM error codes, see Error Handling.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/printdocs/unbindptproviderthunk HRESULT UnbindPTProviderThunk( _In_ HPTPROVIDER
// hProvider );
[DllImport(Lib.PrntvPt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("", MSDNShortId = "ce979c89-9f9d-4e89-b142-beed414caa3f")]
public static extern HRESULT UnbindPTProviderThunk(HPTPROVIDER hProvider);
/// <summary>Provides a handle to a print provider.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HPTPROVIDER : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HPTPROVIDER"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HPTPROVIDER(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HPTPROVIDER"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HPTPROVIDER NULL => new HPTPROVIDER(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="HPTPROVIDER"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HPTPROVIDER h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HPTPROVIDER"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPTPROVIDER(IntPtr h) => new HPTPROVIDER(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HPTPROVIDER h1, HPTPROVIDER h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HPTPROVIDER h1, HPTPROVIDER h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HPTPROVIDER h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HPTPROVIDER"/> that is disposed using <see cref="PTCloseProvider"/>.</summary>
public class SafeHPTPROVIDER : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeHPTPROVIDER"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHPTPROVIDER(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHPTPROVIDER"/> class.</summary>
private SafeHPTPROVIDER() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHPTPROVIDER"/> to <see cref="HPTPROVIDER"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPTPROVIDER(SafeHPTPROVIDER h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => PTCloseProvider(handle).Succeeded;
}
/*
ConvertDevModeToPrintTicketThunk2
ConvertPrintTicketToDevModeThunk2
MergeAndValidatePrintTicketThunk2
PTConvertDevModeToPrintTicket
PTConvertPrintTicketToDevMode
PTGetPrintCapabilities
PTGetPrintDeviceCapabilities
PTGetPrintDeviceResources
PTMergeAndValidatePrintTicket
PTOpenProvider
PTOpenProviderEx
PTQuerySchemaVersionSupport
PTReleaseMemory
*/
}
}

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<ProjectExtensions>
<SupportedDlls>Printing.dll</SupportedDlls>
</ProjectExtensions>
<PropertyGroup>
<Description>PInvoke API (methods, structures and constants imported from Windows Printing.dll.</Description>
<Copyright>Copyright © 2017-2019</Copyright>
<AssemblyTitle>$(AssemblyName)</AssemblyTitle>
<VersionPrefix>3.1.0</VersionPrefix>
<TargetFrameworks>net20;net35;net40;net45;netstandard2.0;netcoreapp2.0;netcoreapp2.1;netcoreapp3.0</TargetFrameworks>
<AssemblyName>Vanara.PInvoke.Printing</AssemblyName>
<PackageId>$(AssemblyName)</PackageId>
<RootNamespace>Vanara.PInvoke</RootNamespace>
<Authors>David Hall</Authors>
<PackageProjectUrl>https://github.com/dahall/vanara</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>Vanara64x64.png</PackageIcon>
<RepositoryUrl>https://github.com/dahall/vanara</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<PackageTags>pinvoke;vanara;net-extensions;interop;Printing</PackageTags>
<NeutralLanguage>en-US</NeutralLanguage>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
<Company>GitHub Community</Company>
<Product>Vanara</Product>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<PackageReleaseNotes></PackageReleaseNotes>
<LangVersion>latest</LangVersion>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\Vanara.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\docs\icons\Vanara64x64.png" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net2')) Or $(TargetFramework.StartsWith('net3')) Or $(TargetFramework.StartsWith('net4')) ">
<Reference Include="System" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) Or $(TargetFramework.StartsWith('netcore')) ">
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Core\Vanara.Core.csproj" />
<ProjectReference Include="..\Shared\Vanara.PInvoke.Shared.csproj" />
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -81,6 +81,9 @@
/// <summary>The power profiling DLL.</summary>
public const string PowrProf = "powrprof.dll";
/// <summary>The prntvpt.dll</summary>
public const string PrntvPt = "prntvpt.dll";
/// <summary>The property system</summary>
public const string PropSys = "propsys.dll";
@ -120,6 +123,9 @@
/// <summary>The win inet</summary>
public const string WinInet = "wininet.dll";
/// <summary>The winspool.dll</summary>
public const string Winspool = "winspool.drv";
/// <summary>The wintrust.dll</summary>
public const string Wintrust = "wintrust.dll";

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="16.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Vanara.PInvoke.Tests</RootNamespace>
<AssemblyName>UnitTest.PInvoke.Printing</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="PrintingTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Core\Vanara.Core.csproj">
<Project>{241f73ee-9298-45c9-b869-a045dff94c03}</Project>
<Name>Vanara.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\PInvoke\Kernel32\Vanara.PInvoke.Kernel32.csproj">
<Project>{842d436f-598c-47d7-b5aa-12399f8ccfe9}</Project>
<Name>Vanara.PInvoke.Kernel32</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\PInvoke\Printing\Vanara.PInvoke.Printing.csproj">
<Project>{d3e1f2b8-d475-4922-b334-919795b858cb}</Project>
<Name>Vanara.PInvoke.Printing</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\PInvoke\Shared\Vanara.PInvoke.Shared.csproj">
<Project>{a5e519e9-feba-4fe3-93a5-b8269bef72f4}</Project>
<Name>Vanara.PInvoke.Shared</Name>
</ProjectReference>
<ProjectReference Include="..\..\CSharpRunner\Shared.csproj">
<Project>{a96cff10-0967-429a-8700-4a86c97c5603}</Project>
<Name>Shared</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="NUnit">
<Version>3.12.0</Version>
</PackageReference>
<PackageReference Include="NUnit3TestAdapter">
<Version>3.15.1</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,248 @@
using NUnit.Framework;
using NUnit.Framework.Constraints;
using System;
using System.Collections;
using System.Linq;
using Vanara.Extensions;
using static Vanara.PInvoke.WinSpool;
namespace Vanara.PInvoke.Tests
{
[TestFixture]
public class PrintingTests
{
private const string connPtrName = "Foobar";
private const string defKey = "PrinterDriverData";
private static readonly string defaultPrinterName = new System.Drawing.Printing.PrinterSettings().PrinterName;
private SafeHPRINTER hprnt;
[OneTimeSetUp]
public void _Setup() => Assert.That(OpenPrinter(defaultPrinterName, out hprnt), ResultIs.Successful);
[OneTimeTearDown]
public void _TearDown() => hprnt?.Dispose();
[Test]
public void AddPrinterTest()
{
const string key = "TestOnly";
const string name = "TestOnlyPrinter";
var pi = GetPrinter<PRINTER_INFO_2>(hprnt);
var pi2 = new PRINTER_INFO_2
{
pPrinterName = name,
pPortName = "LPT1:",
pDriverName = pi.pDriverName,
pPrintProcessor = pi.pPrintProcessor,
Attributes = PRINTER_ATTRIBUTE.PRINTER_ATTRIBUTE_LOCAL
};
var p2 = new SafeHPRINTER(default, false);
try
{
Assert.That(p2 = AddPrinter(null, 2, pi2), ResultIs.ValidHandle);
GetSet("Test", 123, 123U);
GetSet("Test", 123L, 123UL);
GetSet("Test", "123");
GetSet("Test", new byte[] { 1, 2, 3 });
GetSet("Test", new[] { "1", "2", "3" });
GetSet("Test", 123, 123U, REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN);
// Test serializable
var sz = new System.Drawing.Size(4, 4);
GetSet("Test", sz, new byte[] { 4, 0, 0, 0, 4, 0, 0, 0 });
Assert.That(() => SetPrinterData(p2, "Test8", 1, REG_VALUE_TYPE.REG_LINK), Throws.Exception);
Assert.That(() => SetPrinterData(p2, "Test8", 1, REG_VALUE_TYPE.REG_RESOURCE_LIST), Throws.Exception);
Assert.That(ResetPrinter(p2, new PRINTER_DEFAULTS { pDatatype = pi.pDatatype }), ResultIs.Successful);
}
finally
{
Assert.That(DeletePrinter(p2), ResultIs.Successful);
}
void GetSet(string vn, object v, object r = null, REG_VALUE_TYPE t = REG_VALUE_TYPE.REG_NONE)
{
if (r is null) r = v;
Assert.That(SetPrinterData(p2, vn, v, t), ResultIs.Successful);
Assert.That(GetPrinterData(p2, vn), v.GetType().IsArray ? (IResolveConstraint)Is.EquivalentTo((IEnumerable)r) : Is.EqualTo(r));
Assert.That(DeletePrinterData(p2, vn), ResultIs.Successful);
Assert.That(SetPrinterDataEx(p2, key, vn, v, t), ResultIs.Successful);
Assert.That(GetPrinterDataEx(p2, key, vn), v.GetType().IsArray ? (IResolveConstraint)Is.EquivalentTo((IEnumerable)r) : Is.EqualTo(r));
Assert.That(DeletePrinterDataEx(p2, key, vn), ResultIs.Successful);
Assert.That(DeletePrinterKey(p2, key), ResultIs.Successful);
}
}
[Test]
public void AddPrinterConnectionTest()
{
Assert.That(AddPrinterConnection(connPtrName), ResultIs.Successful);
Assert.That(DeletePrinterConnection(connPtrName), ResultIs.Successful);
}
[Test]
public void AddPrinterConnection2Test()
{
var drv = GetPrinter<PRINTER_INFO_2>(hprnt).pDriverName;
Assert.That(AddPrinterConnection2(default, connPtrName, PRINTER_CONNECTION_FLAGS.PRINTER_CONNECTION_MISMATCH, drv), ResultIs.Successful);
Assert.That(DeletePrinterConnection(connPtrName), ResultIs.Successful);
}
[Test]
public void AdvancedDocumentPropertiesTest()
{
var devmodeOut = DEVMODE.Default;
Assert.That(AdvancedDocumentProperties(HWND.NULL, hprnt, defaultPrinterName, ref devmodeOut, DEVMODE.Default), ResultIs.Successful);
Assert.That(AdvancedDocumentProperties(HWND.NULL, hprnt, defaultPrinterName), ResultIs.Successful);
}
[Test]
public void ConnectToPrinterDlgTest()
{
SafeHPRINTER p;
Assert.That(p = ConnectToPrinterDlg(HWND.NULL), ResultIs.ValidHandle);
p.Dispose();
}
[Test]
public void EnumFormsTest()
{
FORM_INFO_1[] res1;
Assert.That(res1 = EnumForms<FORM_INFO_1>(hprnt).ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res1.Select(v => v.pName)));
FORM_INFO_2[] res2;
Assert.That(res2 = EnumForms<FORM_INFO_2>(hprnt).ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res2.Select(v => v.Flags)));
}
[Test]
public void EnumJobsTest()
{
Assert.That(EnumJobs<JOB_INFO_1>(hprnt), Is.Empty);
Assert.That(EnumJobs<JOB_INFO_2>(hprnt), Is.Empty);
Assert.That(EnumJobs<JOB_INFO_3>(hprnt), Is.Empty);
Assert.That(EnumJobs<JOB_INFO_4>(hprnt), Is.Empty);
}
[Test]
public void EnumPrinterDataExTest()
{
var res1 = EnumPrinterDataEx(hprnt, defKey);
Assert.That(res1, Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res1.Select(v => $"{v.valueName}={v.value} ({v.valueType})")));
}
[Test]
public void EnumPrinterDataTest()
{
var res1 = EnumPrinterData(hprnt);
Assert.That(res1, Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res1.Select(v => $"{v.valueName}={v.value} ({v.valueType})")));
}
[Test]
public void EnumPrinterKeyTest()
{
string[] res1;
Assert.That(res1 = EnumPrinterKey(hprnt, "").ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res1));
}
[Test]
public void EnumPrintersTest()
{
PRINTER_INFO_1[] res1;
Assert.That(res1 = EnumPrinters<PRINTER_INFO_1>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res1.Select(v => v.pName)));
PRINTER_INFO_2[] res2;
Assert.That(res2 = EnumPrinters<PRINTER_INFO_2>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res2.Select(v => v.Status)));
//PRINTER_INFO_3[] res3;
//Assert.That(res3 = EnumPrinters<PRINTER_INFO_3>().ToArray(), Is.Not.Empty);
PRINTER_INFO_4[] res4;
Assert.That(res4 = EnumPrinters<PRINTER_INFO_4>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res4.Select(v => v.Attributes)));
PRINTER_INFO_5[] res5;
Assert.That(res5 = EnumPrinters<PRINTER_INFO_5>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res5.Select(v => v.pPortName)));
//PRINTER_INFO_6[] res6;
//Assert.That(res6 = EnumPrinters<PRINTER_INFO_6>().ToArray(), Is.Not.Empty);
//PRINTER_INFO_7[] res7;
//Assert.That(res7 = EnumPrinters<PRINTER_INFO_7>().ToArray(), Is.Not.Empty);
//PRINTER_INFO_8[] res8;
//Assert.That(res8 = EnumPrinters<PRINTER_INFO_8>().ToArray(), Is.Not.Empty);
//PRINTER_INFO_9[] res9;
//Assert.That(res9 = EnumPrinters<PRINTER_INFO_9>().ToArray(), Is.Not.Empty);
}
[Test]
public void FormTest()
{
const string name = "TestOnlyForm";
var form1 = EnumForms<FORM_INFO_1>(hprnt).First();
form1.pName = name;
form1.Flags = FormFlags.FORM_USER;
Assert.That(AddForm(hprnt, form1), ResultIs.Successful);
try
{
FORM_INFO_2 fi2 = default;
Assert.That(() => fi2 = GetForm<FORM_INFO_2>(hprnt, name), Throws.Nothing);
Assert.That(fi2.Flags, Is.EqualTo(FormFlags.FORM_USER));
TestHelper.WriteValues(fi2);
form1.Size = new SIZE(form1.Size.cx / 2, form1.Size.cy / 2);
Assert.That(SetForm(hprnt, name, form1), ResultIs.Successful);
}
finally
{
Assert.That(DeleteForm(hprnt, name), ResultIs.Successful);
}
}
[Test]
public void JobTest()
{
Assert.That(AddJob(hprnt, out var path, out var id), ResultIs.Successful);
try
{
System.IO.File.WriteAllText(path, "Test page.");
JOB_INFO_2 ji2 = default;
Assert.That(() => ji2 = GetJob<JOB_INFO_2>(hprnt, id), Throws.Nothing);
Assert.That(ji2.JobId, Is.EqualTo(id));
TestHelper.WriteValues(ji2);
var jobInfo = new JOB_INFO_1 { JobId = id, Priority = JOB_PRIORITY.MAX_PRIORITY, Status = ji2.Status, pDatatype = ji2.pDatatype };
Assert.That(SetJob(hprnt, id, jobInfo), ResultIs.Successful);
Assert.That(ScheduleJob(hprnt, id), ResultIs.Successful);
}
finally
{
Assert.That(SetJob(hprnt, id, JOB_CONTROL.JOB_CONTROL_DELETE), ResultIs.Successful);
}
}
[Test]
public void PortTest()
{
var port = GetPrinter<PRINTER_INFO_2>(hprnt).pPortName;
Assert.That(ConfigurePort(null, HWND.NULL, port), ResultIs.Successful);
Assert.That(SetPort(null, port, PORT_STATUS.PORT_STATUS_OFFLINE, PORT_STATUS_TYPE.PORT_STATUS_TYPE_ERROR), ResultIs.Successful);
Assert.That(SetPort(null, port, "Off-line", PORT_STATUS_TYPE.PORT_STATUS_TYPE_ERROR), ResultIs.Successful);
Assert.That(SetPort(null, port, 0, 0), ResultIs.Successful);
}
[Test]
public void SpoolFileTest()
{
var hspf = GetSpoolFileHandle(hprnt);
Assert.That(hspf, ResultIs.ValidHandle);
var bytes = new byte[] { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
Kernel32.WriteFile(hspf, bytes, (uint)bytes.Length, out _);
Assert.That(CommitSpoolData(hprnt, hspf, (uint)bytes.Length), ResultIs.Successful);
Assert.That(() => hspf.Dispose(), Throws.Nothing);
}
}
}

View File

@ -181,6 +181,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExplorerBrowserDemo", "Unit
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Windows.Forms.App", "UnitTests\Windows.Forms.App\Windows.Forms.App.csproj", "{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vanara.PInvoke.Printing", "PInvoke\Printing\Vanara.PInvoke.Printing.csproj", "{D3E1F2B8-D475-4922-B334-919795B858CB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Printing", "UnitTests\PInvoke\Printing\Printing.csproj", "{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug (no Unit Tests)|Any CPU = Debug (no Unit Tests)|Any CPU
@ -597,6 +601,18 @@ Global
{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}.Release|Any CPU.Build.0 = Release|Any CPU
{D3E1F2B8-D475-4922-B334-919795B858CB}.Debug (no Unit Tests)|Any CPU.ActiveCfg = Debug|Any CPU
{D3E1F2B8-D475-4922-B334-919795B858CB}.Debug (no Unit Tests)|Any CPU.Build.0 = Debug|Any CPU
{D3E1F2B8-D475-4922-B334-919795B858CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3E1F2B8-D475-4922-B334-919795B858CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3E1F2B8-D475-4922-B334-919795B858CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3E1F2B8-D475-4922-B334-919795B858CB}.Release|Any CPU.Build.0 = Release|Any CPU
{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Debug (no Unit Tests)|Any CPU.ActiveCfg = Debug|Any CPU
{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Debug (no Unit Tests)|Any CPU.Build.0 = Debug|Any CPU
{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -675,6 +691,8 @@ Global
{687F9162-8CA0-4277-B868-4E7F2EC614F8} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11}
{2AACFF7E-F4B1-44F6-92C6-20ACBB647A4D} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11}
{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11}
{D3E1F2B8-D475-4922-B334-919795B858CB} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}