Dear Team,
I'm trying to develop a exe for Network Virtual Printer with my code and business logics. But I'm not able to find any steps/ tutorials. Please assist me on this.
Use Case:User -> Opens a word document -> Print -> Selecting Network Virtual Printer -> User Prompted to Enter Data -> Now Print Handler in server gets triggered and converts word to pdf and do remaining business logics -> Client should be notified with a message.
What I understood so far:For my use case after analyzing network virtual printers, I understood that a virtual printer needs to installed on client machine and network virtual printer needs to be installed on server. And a link needs to be made between these two to make them communicate using remote data which is
PrintJobData.
What I have tried so far:Server Side:I developed a console to install network virtual printer in server. Enabled network sharing in printer after installation.
Here is the code for that: Code:internal class Program
{
private static readonly ApplicationSettings settings = new ApplicationSettings();
private static readonly DocumentWriter documentWriter = new DocumentWriter();
private static readonly string fileName = GetRandomFileName("pdf");
private static Printer virtualPrinter;
private static void Main(string[] args)
{
IConfiguration config = new ConfigurationBuilder()
//.SetBasePath(Directory.GetCurrentDirectory())
.SetBasePath(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location))
.AddJsonFile("appsettings.json", false, true)
.Build();
config.GetSection("Settings").Bind(settings);
LicenseMethods.SetLicense(settings);
if (settings.UninstallPrinter)
{
PrinterMethods.UninstallPrinter(settings);
}
if (settings.InstallPrinter)
{
PrinterMethods.InstallPrinter(settings);
}
//// Not installing or uninstalling. Hook to capture events.
//using Printer virtualPrinter = HookToPrinter(settings.PrinterName);
virtualPrinter = HookToPrinter(settings.PrinterName);
if (virtualPrinter == null)
{
ConsoleMethods.Error("Failed to hook to the printer. Rerun the utility passing -i as an argument to install the printer.");
Environment.Exit((int)ExitCodes.GeneralFailure);
}
do
{
while (!Console.KeyAvailable)
{
// Wait for events
}
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
}
private static Printer HookToPrinter(string printerName)
{
if (PrinterMethods.IsPrinterInstalled(printerName))
{
// Caller will dispose of Printer object.
Printer printer = new Printer(printerName)
{
EnableNetworkPrinting = true
};
printer.EmfEvent += new EventHandler<EmfEventArgs>(VirtualPrinter_EmfEvent);
printer.JobEvent += new EventHandler<JobEventArgs>(VirtualPrinter_JobEvent);
ConsoleMethods.Success($"Hooked to {printerName}");
return printer;
}
return null;
}
private static void VirtualPrinter_EmfEvent(object sender, EmfEventArgs e)
{
// Add to the current document
using Metafile metaFile = new Metafile(e.Stream);
documentWriter.AddPage(new DocumentWriterEmfPage()
{
EmfHandle = metaFile.GetHenhmetafile()
});
}
private static void VirtualPrinter_JobEvent(object sender, JobEventArgs e)
{
string printerName = e.PrinterName;
int jobID = e.JobID;
switch (e.JobEventState)
{
case EventState.JobStart:
ConsoleMethods.Success($"{printerName}: Job {jobID} has started");
//get the remote data sent from client
PrintJobData jobData = virtualPrinter.RemoteData;
string path = Path.Combine(settings.PdfStorePath, fileName);
Directory.CreateDirectory(Path.GetDirectoryName(path));
// Begin writing to a new file
documentWriter.BeginDocument(path, DocumentFormat.Pdf);
break;
case EventState.JobEnd:
ConsoleMethods.Success($"{printerName}: Job {jobID} has ended");
// Finished with file
documentWriter.EndDocument();
// Close the console
Environment.Exit((int)ExitCodes.Success);
break;
default:
virtualPrinter.CancelPrintedJob(jobID);
break;
}
}
private void SetNetworkData(string strData)
{
byte[] bytes = Encoding.ASCII.GetBytes(strData);
//Set initial network data
virtualPrinter.SetNetworkInitialData(bytes);
}
private string GetNetworkData()
{
byte[] bytes;
//Get initial network data
bytes = virtualPrinter.GetNetworkInitialData();
return Encoding.ASCII.GetString(bytes);
}
private static string GetRandomFileName(string extension)
{
return $"{Path.GetFileNameWithoutExtension(Path.GetRandomFileName())}.{extension}";
}
}
Client Side:I need to know whether I need to install a network virtual printer in client or a normal virtual printer in client system. If so after installing how to link the client virtual printer with my server network printer?
I developed a console app for this and below is the code for the same. Please correct me if I'm wrong here.
Client Virtual Printer:Program.cs: Code:internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Virtual Printer Client");
do
{
while (!Console.KeyAvailable)
{
// Wait for events
}
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
}
}
NetworkPrinterClient.cs: Code:public class NetworkPrinterClient : IVirtualPrinterClient
{
public bool PrintJob(PrintJobData printJobData)
{
Console.WriteLine("Job data Ip Address = " + printJobData.IPAddress + " Job ID = " + printJobData.JobID);
//the UserData will be sent to the server machine
//this data can be any user specified data format
printJobData.UserData = new byte[] { (byte)'H', (byte)'E', (byte)'L', (byte)'L', (byte)'O' };
return true;
}
public void Shutdown(string virtualPrinterName)
{
Console.WriteLine("Shutdown received for " + virtualPrinterName + " printer");
}
public bool Startup(string virtualPrinterName, byte[] initialData)
{
Console.WriteLine("Job received from " + virtualPrinterName + "printer");
return true;
}
}
If I run the above virtual print client console app, nothing happens because its obvious from the code that Main method in Program class had no code to invoke NetworkPrinterClient class. So how will the Hello text be retrieved in the
PrintJobData in server?
Client Virtual Print Installer:Here is my Client Virtual Print Installer console app.
Code:
internal class Program
{
private static void Main(string[] args)
{
try
{
Console.WriteLine("Virtual Printer Client Installer");
PrinterInstaller.SetPrinterConnectionDll("Here I need to give the name of Network Virtual Printer in Server?", "What DLL path I should give here? My network virtual printer dll path in server? or any leadtools client print dll path in client machine?", "This should be server machine name right?");
do
{
while (!Console.KeyAvailable)
{
// Wait for events
}
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
}
}
Please look at the embedded questions in the above code at line no 8 in method
PrinterInstaller.SetPrinterConnectionDllWhere I'm stuck now:1. I have network virtual printer installed in server by running my console app. This is perfect.
2. How to install virtual printer in client with my console app?
3. How to link client virtual printer with my server network virtual printer and pass custom data in PrintJobData or by any means.
4. I installed Using Virtual Printer Client Installer windows app from your demo in my client machine. When I gave my server name and clicked refresh, the network virtual printer in my server got listed and for printer dll I gave the path to my
Client Virtual Printer console app dll instead of print demo dll. and it got installed when I tried to print using that printer in my client, I got the error message :
Error loading managed DLL.
I'm stuck on how to connect the pieces that I have developed. Please assist. Your help would be highly appreciated.
Please assist. If I can complete this prototype I can demonstrate this to my organization and get license approved and purchase the license.
Edited by user Tuesday, December 3, 2019 5:44:20 AM(UTC)
| Reason: Not specified