I am using Ghostscipt 9.54 (latest version) for printing a pdf file to my windows printer.
I am using below command:
C:\Users\Pradeep Gupta>"C:\Program Files\gs\gs9.54.0\bin\gswin64c.exe" -dBATCH -dNOPAUSE -dSAFER -dNumCopies=1 -sDEVICE=mswinpr2 -sOutputFile=%printer%"Everycom-58-Series" -f C:\PDF\5601001234040921211737.pdf
GPL Ghostscript 9.54.0 (2021-03-30)
Copyright (C) 2021 Artifex Software, Inc. All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Processing pages 1 through 1.
Page 1
This works fine and works as expected.
Now the same thing I am trying replicate in my .NET C# application. But the issue is that whenever I run my application on my Win 10 laptop, It is showing Print dialog to select the Printer.
Please let me know what I am doing wrong as I am replicating the same argument as I am stating in the above mentioned command.
Below are the code for my C# application:
private static bool DoGhostscriptPrint(string printerName, string pdfFilename)
{
try
{
String[] ghostScriptArguments = { "-dBATCH", "-dNOPAUSE", "-dSAFER", "-dNoCancel",
"-dNumCopies=1", "-sDEVICE=mswinpr2", String.Format("-sOutputFile=\"%printer%{0}\"", printerName),
"-f", pdfFilename};
GhostScript.CallAPI(ghostScriptArguments);
}
catch (Exception ex)
{
Logger.Error("Unable to Print using Ghostscript: " + ex.Message + Environment.NewLine + ex.StackTrace);
}
return false;
}
I am using the code from https://github.com/mephraim/ghostscriptsharp for calling Ghostscript with the args.
Here is the code for Ghosctscript.CallAPI()
/// Calls the Ghostscript API with a collection of arguments to be passed to it
/// </summary>
public static void CallAPI(string[] args)
{
// Get a pointer to an instance of the Ghostscript API and run the API with the current arguments
IntPtr gsInstancePtr;
Logger.Debug("Acquiring Lock to call GS API with Args {0}", String.Join(",", args));
lock (resourceLock)
{
Logger.Debug("Lock Acquired");
GhostScriptNativeWrapper.CreateAPIInstance(out gsInstancePtr, IntPtr.Zero);
try
{
int result = GhostScriptNativeWrapper.InitAPI(gsInstancePtr, args.Length, args);
if (result < 0)
{
throw new ExternalException("Ghostscript conversion error", result);
}
}
finally
{
Logger.Debug("Lock Released");
Cleanup(gsInstancePtr);
Logger.Debug("GS Cleanup Done");
}
}
}
InitAPI code is:
[DllImport("gsdll64.dll", EntryPoint = "gsapi_init_with_args")]
internal static extern int InitAPI(IntPtr instance, int argc, string[] argv);
I have copied the gsdll64.dll from Ghoscript installation.
This issue I am facing since from last one week.
There is no change in the application code since from a month.
Thanks & Regards,
Pradeep Gupta
Related
I'm getting this error when I call my gRPC Golang server from Dart:
Caught error: gRPC Error (code: 12, codeName: UNIMPLEMENTED, message: grpc: Decompressor is not installed for grpc-encoding "gzip", details: [], rawResponse: null, trailers: {})
I have read https://github.com/bradleyjkemp/grpc-tools/issues/19, and it doesn't appear to apply to my issue.
The server is running 1.19.2 on Gcloud Ubuntu.
Dart is running 2.18.2 on Mac Monterey
I have a Dart client calling a Go server. Both appear to be using GZIP for compression.
Dart proto
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
GO proto:
syntax = "proto3";
option go_package = "google.golang.org/grpc/examples/helloworld/helloworld";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
Dart Client code:
import 'package:grpc/grpc.dart';
import 'package:helloworld/src/generated/helloworld.pbgrpc.dart';
Future<void> main(List<String> args) async {
final channel = ClientChannel(
'ps-dev1.savup.com',
port: 54320,
options: ChannelOptions(
credentials: ChannelCredentials.insecure(),
codecRegistry:
CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]),
),
);
final stub = GreeterClient(channel);
final name = args.isNotEmpty ? args[0] : 'world';
try {
final response = await stub.sayHello(
HelloRequest()..name = name,
options: CallOptions(compression: const GzipCodec()),
);
print('Greeter client received: ${response.message}');
} catch (e) {
print('Caught error: $e');
}
await channel.shutdown();
}
The Go gRPC server works fine with a Go gRPC client and BloomRPC.
I'm new to gRPC in general and very new to Dart.
Thanks in advance for any help resolving this issue.
That error that you shared shows that your server doesn't support gzip compression.
The quickest fix is to not use gzip compression in the client's call options, by removing the line:
options: CallOptions(compression: const GzipCodec()),
from your Dart code.
The go-grpc library has an implementation of a gzip compression encoding in package github.com/grpc/grpc-go/encoding/gzip, but it's experimental, so likely not wise to use it in production; or at least you should pay close attention to it:
// Package gzip implements and registers the gzip compressor
// during the initialization.
//
// Experimental
//
// Notice: This package is EXPERIMENTAL and may be changed or removed in a
// later release.
If you want to use it in your server, you just need to import the package; there is no user-facing code in the package:
import (
_ "github.com/grpc/grpc-go/encoding/gzip"
)
The documentation about compression for grpc-go mentions this above package as an example of how your implement such a compressor.
So you may also want to copy the code to a more stable location and take responsibility for maintaining it yourself, until there is a stable supported version of it.
I want to create an output file in a threadsafe manner, and only if it does not exist. I want to use the file system for synchronization. With open() I would use the flags O_RWRONLY|O_CREAT|O_EXCL. Is there a way to do this in C++17 using the iostream or fstream ?
Prior to C++23 there is no way of opening an ofstream in exclusive mode.
Workaround: Use std::fopen which has this capability since C++17.
Example:
#include <cstdio>
// Mode "x" to make it fail if it already exists
std::FILE* fp = std::fopen("filename", "wx");
if(fp) {
// created exclusively
// work with fp ...
std::fclose(fp);
}
If you really want an ofstream you could create a helper function:
template<class Stream>
Stream open_exclusively(const std::string& filename) {
Stream rv;
if(std::FILE* fp = std::fopen(filename.c_str(), "wx"); fp) {
std::fclose(fp);
// overwrite the file that was created exclusively:
rv.open(filename);
} else {
// could not create file exclusivly, set the failbit in the stream:
rv.setstate(Stream::failbit);
}
return rv;
}
int main() {
auto os = open_exclusively<std::ofstream>("filename");
if(os) {
std::cout << "file created exclusively\n";
}
}
Demo
Edit:
Even though the above demo is compliant and works on all platforms I've tested it - wine (v6.16) can't handle it, so I opened a bug report at bugs.winehq.org. You can follow the progress here:
Standard library call fopen(..., "wx") not recognized - causes destruction of data
Edit 2:
The Wine bugfix ucrtbase: Add support for x mode in fopen is now included in Wine 6.20 so after upgrading to 6.20 (or later), this will be working as it should in Wine too.
From C++23 you can use the std::ios::noreplace openmode:
std::ofstream os("filename", std::ios::noreplace);
if(os) {
std::cout << "file created exclusively\n";
}
I used JSNI and it did not work in the latest browsers version(eg.chrome, IE, Firefox)! I wrote this code below :
public static native boolean detectJavaVersion() /*-{
try {
var javaVersions = $wnd.deployJava.getJREs();
alert("Your windows Java version is : " + javaVersions);
if (javaVersions.length == 0) {
alert("You have not installed any types of Java in your system");
return false;
}
if (javaVersions < "1.8") {
alert("Java version is less than 8");
return false;
} else {
alert("Java version is 8 or more than it");
return true;
}
}
catch
(err) {
var exceptionMsg = err.message;
alert("Exception is : " + exceptionMsg);
}
}-*/;
I tried to fix it over a week!!!
Could someone please gives me an advice.
Thanks a lot.
There is no Java in modern browsers (Chrome, Firefox, Edge, Safari), which is probably why your code fails.
You can still write Java code and let GWT compile it into JavaScript, that way it can run in the browser. The Java features you can use depend on GWT compiler support, not on the browser.
Got a weird question for you. Recently upleveled my old project from java 7(jdk1.7.0_10) to java 8(1.8.0.91.x86_64). In java 7 it printed the post script file with no issues and now it is printing the postscript file as plain text instead of converting the file. This is on a redhat linux environment. Simply I am trying to print a string containing a post script file of a file itself.
Here is my original code
DocFlavor flavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
PrintService pService = PrintServiceLookup.lookupDefaultPrintService();
// In a field environment, send to the printer
if (System.getenv("USER_DEFINED_RELTOP") == null || pfr.exists()) {
if (pService.getName().isEmpty()) {
LOGGER.error("No printer selected");
} else {
LOGGER.info("Printing to " + pService.getName());
DocPrintJob pj = pService.createPrintJob();
try {
InputStream is = new ByteArrayInputStream(data.getBytes("UTF8"));
Doc doc = new SimpleDoc(is, flavor, null);
PrintJobWatcher pjw = new PrintJobWatcher(pj);
pj.print(doc, null);
pjw.waitForDone();
is.close();
} catch (PrintException | IOException e) {
LOGGER.error(e);
} // try block
} // no printer selected
// Otherwise, send to a file
} else {
That worked fine in java 7, I updated it to the oracle spec found here for java 8.
https://docs.oracle.com/javase/8/docs/api/javax/print/PrintService.html#createPrintJob--
https://docs.oracle.com/javase/8/docs/technotes/guides/jps/spec/printing.fm6.html
DocFlavor psFlavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
attrs.add(MediaSizeName.ISO_A4);
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(psFlavor,
attrs);
File pfr = new File(PFR_INDICATOR);
// In a field environment, send to the printer
if (System.getenv("USER_DEFINED_RELTOP") == null || pfr.exists()) {
//Check we have a printer capable of post script
if (pservices.length > 0) {
LOGGER.info("Printing to " + pservices[0].getName());
DocPrintJob pj = pservices[0].createPrintJob();
try {
InputStream fis = new ByteArrayInputStream(data.getBytes("UTF8"));
//byte[] ba =data.getBytes("UTF8");
Doc doc = new SimpleDoc(fis, psFlavor, null);
LOGGER.info("Doc Flavor " + doc.getDocFlavor());
PrintJobWatcher pjw = new PrintJobWatcher(pj);
LOGGER.info("PrintJob Attributes : " + pj.getAttributes());
pj.print(doc, attrs);
pjw.waitForDone();
fis.close();
} catch (IOException e) {
LOGGER.error(e);
NotificationDialog.show(NotificationDialog.NOTICE_TYPE.ERROR, PRINT_ERROR);
} catch (PrintException e) {
LOGGER.error(e);
}
} else { // no printer selected
This gives me an error java.awt.print.PrinterIOException: java.io.IOException: /usr/bin/lpr: where it looks to not find lpr.
If I keep it the way it was originally (not write to file) it prints the postscript as plain text even if adding the check to check if the printer is post script capable. If I use the new way of printing file I get a lpr not found error. If I print the PS document using the command lpr it converts it as expected and prints fine. If I use lpr -l that doesn't format it prints it document as plain text as well.
Any suggestion/help would be great. I am lost on what to do. I really don't want to convert it to an image and print that.
At a guess I'd say that your printer is an HP or at least PCL + PS printer, not a pure PostScript-only printer.
In that case you generally need to prepend the PostScript with a language selection PJL string. If you don't do this then it usually defaults to PCL and if you don't send any PCL commands (which all begin with 0x1B) then everything is treated as plain ASCII text. That would explain why both your application and lpr -l end up writing text, but lpr itself doesn't (presumably it adds the PJL).
You could try prepending the PostScript file with something like:
%-12345X#PJL JOB
#PJL ENTER LANGUAGE=POSTSCRIPT
NB the first byte there, before the % should be a 0x1b ESC character, but I can't readily paste binary....
Try sending the file with lpr -l if that works then you could try your old printing method.
can't run the automated project in testcomplete when calls from jenkins.
In our continuous integration part ,the project is automated using testcomplete and it is calling through jenkins with the help of bat file.The scripts inside the bat file is
"C:\Program Files\Automated QA\TestComplete 7\Bin\TestComplete.exe " "D:\Test Complete7 Projects\ProjectInput_AllSamples\ProjecInputs.pjs" /r /p:Samples /rt:Main "iexplore" /e
It will open testcomplete and iexplorer ,but it is not filling the data(automation).
It is working perfectly when we directly call the bat file with out jenkins.Is there any solution
From your description it sounds like something in Windows stopping you from allowing your test application to work normally. It might be the fact that the second user could be a problem but I can't confirm that as I was not able find any definite explanations of how it works in Windows XP. I am pretty sure that this won't work on a Windows Vista, 7, 8 or server machine though because of the changes in architecture.
It sounds like the best solution is to make sure that your automated UI tests are started by an interactive user. When I was trying to add automated testing to our builds we used TestComplete 7 on a Windows XP SP2 virtual machine. In order to start our tests as an interactive user we:
Made an user log on when windows started, this way there was always an interactive user which means there was an actual desktop session which has access to the keyboard / mouse. I seem to remember (but can't find any links at the moment) that without an interactive user there is no active desktop that can access the keyboard / mouse.
We wrote a little app that would start when the interactive user logged on. This app would look at a specific file and when that file changed / was created it would read the file and start the application. The code for this app looked somewhat like this:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ApplicationStarter
{
class Program
{
// The string used to indicate that the application should quit.
private const string ExitString = "exit";
// The path which is being watched for changes.
private static string s_LoadFilePath;
static void Main(string[] args)
{
try
{
{
Debug.Assert(
args != null,
"The arguments array should not be null.");
Debug.Assert(
args.Length == 1,
"There should only be one argument.");
}
s_LoadFilePath = args[0];
{
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"Watching: {0}",
s_LoadFilePath));
}
if (File.Exists(s_LoadFilePath))
{
RunApplication(s_LoadFilePath);
}
using (var watcher = new FileSystemWatcher())
{
watcher.IncludeSubdirectories = false;
watcher.NotifyFilter =
NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
watcher.Path = Path.GetDirectoryName(s_LoadFilePath);
watcher.Filter = Path.GetFileName(s_LoadFilePath);
try
{
watcher.Created += OnConfigFileCreate;
watcher.EnableRaisingEvents = true;
// Now just sit here and wait until hell freezes over
// or until the user tells us that it has
string line = string.Empty;
while (!string.Equals(line, ExitString, StringComparison.OrdinalIgnoreCase))
{
line = Console.ReadLine();
}
}
finally
{
watcher.Created -= OnConfigFileCreate;
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static void RunApplication(string configFilePath)
{
var appPath = string.Empty;
var arguments = string.Empty;
using (var reader = new StreamReader(configFilePath, Encoding.UTF8))
{
appPath = reader.ReadLine();
arguments = reader.ReadLine();
}
// Run the application
StartProcess(appPath, arguments);
}
private static void StartProcess(string path, string arguments)
{
var startInfo = new ProcessStartInfo();
{
startInfo.FileName = path;
startInfo.Arguments = arguments;
startInfo.ErrorDialog = false;
startInfo.UseShellExecute = true;
startInfo.RedirectStandardOutput = false;
startInfo.RedirectStandardError = false;
}
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"{0} Starting process {1}",
DateTime.Now,
path));
using (var exec = new Process())
{
exec.StartInfo = startInfo;
exec.Start();
}
}
private static void OnConfigFileCreate(
object sender,
FileSystemEventArgs e)
{
Console.WriteLine(
string.Format(
CultureInfo.InvariantCulture,
"{0} File change event ({1}) for: {2}",
DateTime.Now,
e.ChangeType,
e.FullPath));
// See that the file is there. If so then start the app
if (File.Exists(e.FullPath) &&
string.Equals(s_LoadFilePath, e.FullPath, StringComparison.OrdinalIgnoreCase))
{
// Wait for a bit so that the file is no
// longer locked by other processes
Thread.Sleep(500);
// Now run the application
RunApplication(e.FullPath);
}
}
}
}
This app expects the file to have 2 lines, the first with the app you want to start and the second with the arguments, so in your case something like this:
C:\Program Files\Automated QA\TestComplete 7\Bin\TestComplete.exe
"D:\Test Complete7 Projects\ProjectInput_AllSamples\ProjecInputs.pjs" /r /p:Samples /rt:Main "iexplore" /e
You should be able to generate this file from Jenkins in a build step.
Finally you may need to watch the TestComplete process for exit so that you can grab the results at the end but I'll leave that as an exercise to reader.
If you are running Jenkins (either master or slave) as a windows service, ensure it is running as a user and not as Local System.
We also do the same as Gentlesea's recommends, we run TestExecute on our Jenkins Slaves and keepo the TestComplete licenses for the people designing the TestComplete scripts.