mirror of https://github.com/dahall/Vanara.git
Added initial PInvoke.Printing project with winspool.h implementations
parent
f74d478b28
commit
945d381524
|
@ -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
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
@ -81,6 +81,9 @@
|
||||||
/// <summary>The power profiling DLL.</summary>
|
/// <summary>The power profiling DLL.</summary>
|
||||||
public const string PowrProf = "powrprof.dll";
|
public const string PowrProf = "powrprof.dll";
|
||||||
|
|
||||||
|
/// <summary>The prntvpt.dll</summary>
|
||||||
|
public const string PrntvPt = "prntvpt.dll";
|
||||||
|
|
||||||
/// <summary>The property system</summary>
|
/// <summary>The property system</summary>
|
||||||
public const string PropSys = "propsys.dll";
|
public const string PropSys = "propsys.dll";
|
||||||
|
|
||||||
|
@ -120,6 +123,9 @@
|
||||||
/// <summary>The win inet</summary>
|
/// <summary>The win inet</summary>
|
||||||
public const string WinInet = "wininet.dll";
|
public const string WinInet = "wininet.dll";
|
||||||
|
|
||||||
|
/// <summary>The winspool.dll</summary>
|
||||||
|
public const string Winspool = "winspool.drv";
|
||||||
|
|
||||||
/// <summary>The wintrust.dll</summary>
|
/// <summary>The wintrust.dll</summary>
|
||||||
public const string Wintrust = "wintrust.dll";
|
public const string Wintrust = "wintrust.dll";
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
Vanara.sln
18
Vanara.sln
|
@ -181,6 +181,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExplorerBrowserDemo", "Unit
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Windows.Forms.App", "UnitTests\Windows.Forms.App\Windows.Forms.App.csproj", "{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Windows.Forms.App", "UnitTests\Windows.Forms.App\Windows.Forms.App.csproj", "{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug (no Unit Tests)|Any CPU = Debug (no Unit Tests)|Any CPU
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -675,6 +691,8 @@ Global
|
||||||
{687F9162-8CA0-4277-B868-4E7F2EC614F8} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11}
|
{687F9162-8CA0-4277-B868-4E7F2EC614F8} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11}
|
||||||
{2AACFF7E-F4B1-44F6-92C6-20ACBB647A4D} = {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}
|
{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
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}
|
SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}
|
||||||
|
|
Loading…
Reference in New Issue