How can I install/add a virtual printer using c# commands? - c#

I am trying to install a virtual printer (for all versions of Windows) with a Windows desktop application. I want this printer to be available in the drop down list in the print dialog (especially from Office).
I am trying with this code:
public static void installPrinter(string printerName)
{
string arg;
arg = "printui.dll , PrintUIEntry /if /b " + "\"" + printerName + "\"" + #" /f C:\Windows\inf\ntprint.inf /r " + "\"" + "lpt1:" + "\"" + " /m " + "\"" + "Brother DCP-116C" + "\""; //initial args
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = "rundll32.exe";
p.Arguments = arg;
p.WindowStyle = ProcessWindowStyle.Hidden;
try
{
Process.Start(p);
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.ToString());
}
}
but it doesn't work. Any suggestions?

After a lot of research I made it work on win 7,8,8.1,10 on both x84 and x64 platforms (without any embeded drivers).
Here is the code:
public static void installPrinter(string printerName) //works on win 7,8,8.1,10 on both x84 and x64
{
//https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/rundll32-printui
// /if Installs a printer by using an .inf file.
// /b[name] Specifies the base printer name.
// /#[file] Specifies a command-line argument file and directly inserts the text in that file into the command line.
// /f[file] Species the Universal Naming Convention (UNC) path and name of the .inf file name or the output file name, depending on the task that you are performing. Use /F[file] to specify a dependent .inf file.
// /r[port] Specifies the port name.
// /m[model] Specifies the driver model name. (This value can be specified in the .inf file.)
string arg;
arg = "printui.dll , PrintUIEntry /if /b " + "\"" + printerName + "\"" + #" /f C:\Windows\inf\ntprint.inf /r " + "\"" + "lpt1:" + "\"" + " /m " + "\"" + "Generic / Text Only" + "\"";
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = "rundll32.exe";
p.Arguments = arg;
p.WindowStyle = ProcessWindowStyle.Hidden;
try
{
Process.Start(p);
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.ToString());
}
}

Related

SQL CLR calling Process.Start hangs or fails

I have checked and there are many posts similar but I cannot solve this. This is a SQL CLR proc to run an exe that parses PDF files. I can run same code as myself in console app. Permissions are not an issue. I am dumping to event log and the ProcessStartInfo is full formed. UseShellExecute - I am not certain. I have also created a .bat file to execute the code - run it manually - it runs fine. Via this CLR program ? Hangs or runs right away but does nothing. At wits end. My goal was to create the CLR using the Nuget from itext but I had a real hard time installing. SQL CLR doesnt support it but I tried anyway.
Thanks in advance.
[Microsoft.SqlServer.Server.SqlProcedure]
public static void PDFToCSVViaExe_CLR()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
string args = #"\\app\Systems\Universal";
args = " \"" + args + "\"" + " \"" + "*" + "\"" + " \"" + "LVM" + "\"";
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = true;
startInfo.FileName = "c:\\SqlCLR\\PDFRipper\\PDFToCSV.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = args;
EventLog.WriteEntry(".NET Runtime", startInfo.FileName.ToString()+" " + args, EventLogEntryType.Warning, 1000);
string folder = "C:\\SqlCLR\\PDFRipper\\LVM.bat";
try
{
//using (new ImpersonationNamespace.Impersonation("domain", "user", "password"))
{
EventLog.WriteEntry(".NET Runtime", System.Security.Principal.WindowsIdentity.GetCurrent().Name + " OR " + Environment.UserName, EventLogEntryType.Warning, 1000);
folder = System.IO.Path.GetDirectoryName(folder);
if (!Directory.Exists(folder))
{
throw (new Exception("Directory does not exist for " + folder));
}
else
{ EventLog.WriteEntry(".NET Runtime", folder + " exists.", EventLogEntryType.Warning, 1000); }
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
}
catch (Exception ex)
{
using (EventLog EventLog = new EventLog("Application"))
{
EventLog.Source = "Application";
//eventLog.WriteEntry(ex.Message);
EventLog.WriteEntry(".NET Runtime", ex.Message + "Trace" + ex.StackTrace, EventLogEntryType.Warning, 1000);
//eventLog.WriteEntry(".NET Runtime", ex.Message, EventLogEntryType.Warning, 1000);
}
}

Mono: how to run a bash command on a new console/terminal window?

How can I run a bash command using Mono (System.Diagnostics.Process) in a new console/terminal window? It works fine on Windows, where a new console window is opened to run the command. On Linux and macOS, the command runs on the same terminal window which I've used to open the app. I've tried all CreateNoWindow/UseShellExecute combinations but none of them worked for me.
Edit: here's the code:
var startInfo = new ProcessStartInfo();
switch (ThermoCS.PlatformCheck.RunningPlatform())
{
case ThermoCS.PlatformCheck.Platform.Windows:
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Environment.CurrentDirectory + "\\ThermoCS\\" + item.Key + ".exe";
if (item.Key.Contains("1"))
{
startInfo.Arguments = Model;
}
else
{
startInfo.Arguments = Model + " " + MixRule;
}
break;
case ThermoCS.PlatformCheck.Platform.Linux:
startInfo.WorkingDirectory = Environment.CurrentDirectory;
var ldc = "LD_LIBRARY_PATH=" + Environment.CurrentDirectory + "/ThermoCS/; export LD_LIBRARY_PATH";
//startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "/bin/bash";
if (item.Key.Contains("1"))
{
startInfo.Arguments = "-c \" " + ldc + " && chmod +x ThermoCS/" + item.Key + " && ./ThermoCS/" + item.Key + " " + Model + " \"";
}
else
{
startInfo.Arguments = "-c \" " + ldc + " && chmod +x ThermoCS/" + item.Key + " && ./ThermoCS/" + item.Key + " " + Model + " " + MixRule + " \"";
}
break;
case ThermoCS.PlatformCheck.Platform.Mac:
var basedir = Directory.GetParent(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).Parent.FullName;
var ldcosx = "export DYLD_LIBRARY_PATH=" + basedir + "/Contents/MonoBundle/ThermoCS/";
startInfo.WorkingDirectory = basedir;
//startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "/bin/bash";
if (item.Key.Contains("1"))
{
startInfo.Arguments = "-c \" " + ldcosx + " && chmod +x Contents/MonoBundle/ThermoCS/" + item.Key + " && ./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " \"";
}
else
{
startInfo.Arguments = "-c \" " + ldcosx + " && chmod +x Contents/MonoBundle/ThermoCS/" + item.Key + " && ./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " " + MixRule + " \"";
}
break;
}
Process proc = Process.Start(startInfo);
As I've described above, the command runs just fine. The problem is that on Linux and macOS it does on the same terminal window which owns the currently running app. I want it to run on a new terminal window.
Thanks in advance!
What I did was I wrote a simple bash script that I placed in my Debug/Release/Whatever folder (folder of the executable of C# program.) Lets call the bash script, first.sh
In this bash folder, I would call another bash from another directory, the bash I was looking to run initially. Lets call this bash script, second.sh
In my C# code I will call first.sh like this:
string command = string.Format("{0}", "./first.sh");
Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "gnome-terminal";
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.RedirectStandardInput = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.StartInfo.Arguments = " -e \" " + command + " \"";
proc.Start();
My first.sh would change to the directory where my second.sh is:
#!/bin/sh
# This is a comment!
echo hello world # This is just a test to see if it is being called
cd ~
cd home/scripts
(exec "./second")
This whole process would physically open up a new terminal and execute commands within it from C# code.
Here is a good tutorial on how to write bash scripts: tutorial on bash scripting in linux
I've found the solution by myself. It involves saving the commands in a script file, making it executable and calling xterm on Linux or Terminal.app on macOS:
var startInfo = new ProcessStartInfo();
switch (ThermoCS.PlatformCheck.RunningPlatform())
{
case ThermoCS.PlatformCheck.Platform.Windows:
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Environment.CurrentDirectory + "\\ThermoCS\\" + item.Key + ".exe";
if (item.Key.Contains("1"))
{
startInfo.Arguments = Model;
}
else
{
startInfo.Arguments = Model + " " + MixRule;
}
break;
case ThermoCS.PlatformCheck.Platform.Linux:
startInfo.WorkingDirectory = Environment.CurrentDirectory;
var ldc = "LD_LIBRARY_PATH=" + Environment.CurrentDirectory + "/ThermoCS/; export LD_LIBRARY_PATH";
var scriptl = new StringBuilder();
scriptl.AppendLine("#!/bin/bash");
scriptl.AppendLine("cd '" + Environment.CurrentDirectory + "'");
scriptl.AppendLine(ldc);
scriptl.AppendLine("chmod +x ThermoCS/" + item.Key);
if (item.Key.Contains("1"))
{
scriptl.AppendLine("./ThermoCS/" + item.Key + " " + Model);
}
else
{
scriptl.AppendLine("./ThermoCS/" + item.Key + " " + Model + " " + MixRule);
}
var filepathl = Path.GetTempFileName();
File.WriteAllText(filepathl, scriptl.ToString());
Process.Start("/bin/bash", "-c \" chmod +x " + filepathl + " \"");
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "xterm";
startInfo.Arguments = "-e '" + filepathl + "'";
break;
case ThermoCS.PlatformCheck.Platform.Mac:
var basedir = Directory.GetParent(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).Parent.FullName;
var ldcosx = "export DYLD_LIBRARY_PATH=" + basedir + "/Contents/MonoBundle/ThermoCS/";
var script = new StringBuilder();
script.AppendLine("#!/bin/bash");
script.AppendLine("cd '" + basedir + "'");
script.AppendLine(ldcosx);
script.AppendLine("chmod +x Contents/MonoBundle/ThermoCS/" + item.Key);
if (item.Key.Contains("1"))
{
script.AppendLine("./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model);
}
else
{
script.AppendLine("./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " " + MixRule);
}
var filepath = Path.GetTempFileName();
File.WriteAllText(filepath, script.ToString());
Process.Start("/bin/bash", "-c \" chmod +x " + filepath + " \"");
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "open";
startInfo.Arguments = "-a Terminal.app " + filepath;
break;
}
Process proc = Process.Start(startInfo);

running a exe file from web api on iis server not working

I want to execute an exe file on to The Web API as and when user request comes. It is working perfectly but when I am hosting web API to server the exe file is not executed when user request comes. What to do for executing the exe file from web API on IIS server?
Here is the process starting code:
public static void Start(long campaign_id, long contact_id, string startDate, string endDate, string user)
{
try
{
//WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.WorkingDirectory = #"C:\";
startInfo.Arguments = "/c sparkclr-submit --master " + ConfigurationManager.AppSettings["SparkMaster"] + " --driver-class-path " + AppDomain.CurrentDomain.BaseDirectory + "Engine\\mysql.jar " + "--exe CmAnalyticsEngine.exe " + AppDomain.CurrentDomain.BaseDirectory + "Engine " + campaign_id + " " + contact_id + " " + startDate + " " + endDate + " " + user;
process.StartInfo = startInfo;
process.Start();
}
catch (Exception e)
{
LogWritter.WriteErrorLog(e);
}
}
How are you starting the exe? You have any error logs?
You can try using the verb runas in Process.Start to execute the exe file as an Administrator.
ProcessStartInfo proc = new ProcessStartInfo();
proc.WindowStyle = ProcessWindowStyle.Normal;
proc.FileName = myExePath;
proc.CreateNoWindow = false;
proc.UseShellExecute = false;
proc.Verb = "runas"; //this is how you pass this verb

windres: The filename, directory name, or volume label syntax is incorrect

I'm using windows 10.
I'm trying to compile a c++ file within c# using MinGW(the MinGW folder is in the projects directory), but it won't compile a resource script (using windres).
Whenever I use windres in cmd it says: "C:/Users/username/AppData/Local/Temp/my.rc:1: unrecognized escape sequence".
but still works.
But when I run the exact same command through c# (by creating a process) it doesn't work at all and says: "The filename, directory name, or volume label syntax is incorrect.".
My code:
String tempDir = Path.GetTempPath();
String file = tempDir + "my.rc";
using (StreamWriter writer = new StreamWriter(file, false, Encoding.ASCII))
{
if (!textIcon.Text.Equals(""))
await writer.WriteLineAsync("25 ICON \"" + textIcon.Text + "\"");
if (checkAdmin.Checked)
{
String manifest = tempDir + #"\manifest.xml";
createManifest(manifest);
await writer.WriteLineAsync("55 24 \"" + manifest + "\"");
}
}
String args2 = "/c \"" + Path.Combine(gccLocation, "windres.exe") + "\" -o \"" + Path.Combine(tempDir, "my.o").Replace("\\", "/") + "\" \"" + file.Replace("\\", "/") + "\"";
//Debug
//args2 = "/k echo " + args2;
ProcessStartInfo psi2 = new ProcessStartInfo();
psi2.FileName = "CMD.exe";
psi2.Arguments = args2;
psi2.UseShellExecute = false;
psi2.CreateNoWindow = true;
//Debug
//psi2.CreateNoWindow = false;
Process windres = Process.Start(psi2);
windres.WaitForExit();
if(windres.ExitCode != 0)
{
MessageBox.Show("Error: Could not create resource file (" + windres.ExitCode + ")");
}
Ended up using a batch file to run the command.
String args2 = "windres.exe -i \"" + Path.GetFullPath(file) + "\" -o \"" + Path.Combine(tempDir, "my.o") + "\"" ;
using (StreamWriter writer = new StreamWriter(tempDir + #"\my.bat", false, Encoding.ASCII))
{
await writer.WriteLineAsync("#echo off");
await writer.WriteLineAsync("cd " + Path.GetFullPath(gccLocation));
await writer.WriteLineAsync(args2);
}
//Debug
//args2 = "/k echo " + args2;
ProcessStartInfo psi2 = new ProcessStartInfo();
psi2.FileName = tempDir + #"\my.bat";
psi2.UseShellExecute = false;
psi2.CreateNoWindow = true;
//Debug
//psi2.CreateNoWindow = false;
Process windres = Process.Start(psi2);
windres.WaitForExit();

cmd command is not recognized as > an internal or external command, operable program or batch file

when i run this code.
public void WaterMarkingUsingCommandLine(string videopath, string imagepath)
{
string OutputFolder = AppDomain.CurrentDomain.BaseDirectory + "Output\\" + System.IO.Path.GetFileNameWithoutExtension(videopath) + "_Output.mp4";
string ffmpegPath = #""""+AppDomain.CurrentDomain.BaseDirectory + #"ffmpeg.exe""";
string ffmpegParams = #"-i """+videopath+#""" -i """+imagepath+#""" -filter_complex ""overlay=10:10"" """+OutputFolder+#"""";
Process ffmpeg = new Process();
ffmpeg.StartInfo.FileName = "cmd.exe";
ffmpeg.StartInfo.Arguments = "/k " + ffmpegPath + " " + ffmpegParams;
ffmpeg.Start();
}
I see this in cmd.
'c:\users\jafar.baltidynamolog\documents\visual' is not recognized as
an internal or external command, operable program or batch file.
C:\Users\jafar.baltidynamolog\Videos\videos>
The problem seems to be due to space.As told in other questions, I have added commas around the filenames but still it is not working.
Update
By Debugging i found that value of
ffmpeg.StartInfo.Arguments=
"/k \"c:\users\jafar.baltidynamolog\documents\visual studio
2010\Projects\VideoProjectBilal\VideoProjectBilal\bin\Debug\ffmpeg.exe\"
-i \"C:\Users\jafar.baltidynamolog\Videos\videos\SampleVideo_360x240_2mb.mp4\"
-i \"C:\Users\jafar.baltidynamolog\Videos\images\2.png\" -filter_complex \"overlay=10:10\" \"c:\users\jafar.baltidynamolog\documents\visual studio
2010\Projects\VideoProjectBilal\VideoProjectBilal\bin\Debug\Output\SampleVideo_360x240_2mb_Output.mp4\""
Try changing this line:
string ffmpegPath = #""""+AppDomain.CurrentDomain.BaseDirectory + #"ffmpeg.exe""";
for this: string ffmpegPath = #"""" + AppDomain.CurrentDomain.BaseDirectory + "ffmpeg.exe";
Update
Try this:
string OutputFolder = AppDomain.CurrentDomain.BaseDirectory + "Output\\" + System.IO.Path.GetFileNameWithoutExtension(videopath) + "_Output.mp4";
string ffmpegPath =AppDomain.CurrentDomain.BaseDirectory + "ffmpeg.exe";
string ffmpegParams = "-i " + videopath + " -i " + imagepath + " -filter_complex overlay=10:10 " + OutputFolder ;

Categories

Resources