I have an Azure Function where I convert an HTML to PDF and then download the result.
Yesterday I updated the function to version 4 and .NET 6 and I also saw that the BrowserFetcher.DefaultRevision is obsoleted and I replaced it with recommended BrowserFetcher.DefaultChromiumRevision and the function is not working anymore after publish.
I also tried locally but there is all good. The error I received is Invalid URI: The hostname could not be parsed. and I suspect the Puppeteer.
This is my Startup function code:
public override void Configure(IFunctionsHostBuilder builder)
{
var bfOptions = new BrowserFetcherOptions();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
bfOptions.Path = Path.GetFullPath("mounted");
}
var bf = new BrowserFetcher(bfOptions);
try
{
bf.DownloadAsync(BrowserFetcher.DefaultChromiumRevision).Wait();
}
catch (Exception)
{
string zipPath = Path.Combine(bf.DownloadsFolder, $"download-{bf.Platform}-{BrowserFetcher.DefaultChromiumRevision}.zip");
string folderPath = Path.Combine(bf.DownloadsFolder, $"{bf.Platform}-{BrowserFetcher.DefaultChromiumRevision}");
using (var process = new Process())
{
process.StartInfo.FileName = "unzip";
process.StartInfo.Arguments = $"\"{zipPath}\" -d \"{folderPath}\"";
process.Start();
process.WaitForExit();
}
new FileInfo(zipPath).Delete();
}
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IPdfPrinterService>((s) =>
{
return new ChromiumPdfPrinterService(bf.GetExecutablePath(BrowserFetcher.DefaultChromiumRevision));
});
}
Has anyone else faced this problem?
I found the issue. That was caused by RazorLight upgrade to stable version 2.0.0.
Rollback to version 2.0.0-rc.3 works fine.
Here is the GitHub issue: https://github.com/toddams/RazorLight/issues/481
I'm not sure what the correct question for my case would be but I'll try to describe as good as I can. I have to mention that I don't have much knowledge of this language, I'm using it strictly for the executable of my appplication, mainly I mess around with Java. So I have an app that only starts up if it finds java in my PC. I'm using something like this:
ProcessStartInfo startJava = new ProcessStartInfo("java", JavaProcessArguments());
startJava.CreateNoWindow = !client.ShowConsole;
startJava.UseShellExecute = false;
But, let's say I want to use openJDK, then I would have to change "java" to something like this:
ProcessStartInfo startJava = new ProcessStartInfo
(#"C:\Program Files (x86)\Java\openJDK_1.7\bin\java.exe", JavaProcessArguments());
Moving on, I wanted to start openJDK FIRST, even if java is present, so I wrote a condition that does that:
private void StartTheProcess()
{
string pathJDK = #"C:\Program Files (x86)\Java\openJDK_1.7\bin\";
bool isDirJDK7 = Directory.Exists(pathJDK);
if (isDirJDK7)
{
ProcessStartInfo startJava = new ProcessStartInfo(#"C:\Program Files (x86)\Java\openJDK_1.7\bin\java.exe", JavaProcessArguments());
startJava.CreateNoWindow = !client.ShowConsole;
startJava.UseShellExecute = false;
try
{
using (Process p = Process.Start(startJava))
{
p.WaitForExit();
}
}
catch (Win32Exception ex)
{
some error...
}
catch (Exception e)
{
some error...
}
}
else
{
ProcessStartInfo startJava = new ProcessStartInfo("java", JavaProcessArguments());
startJava.CreateNoWindow = !client.ShowConsole;
startJava.UseShellExecute = false;
try
{
using (Process p = Process.Start(startJava))
{
p.WaitForExit();
}
}
catch (Win32Exception ex)
{
some error...
}
catch (Exception e)
{
some error...
}
}
}
Now let's suppose I have more openJDK versions in the "C:\Program Files (x86)\Java\" folder: openJDK_1.7, openJDK_1.7_u1, openJDK_1.8, so on, and I want to start the latest one. How should I accomplish this? I think one method would be to compare the subfolders names found there but I don't really know how to. The content of all the subfolders is identical and the names of the subfolders have the same construction (openJDK_1.X / openJDK_1.X_uYZ). Could you help me, based on this poorly (most likely) code? :D
There are a few things you could try,
Split the directory name string by
var version = string.split('_'), and then the version would be version[1] = "1.7", you can convert all of these into doubles/decimals/floats,etc and just sort the data out, get the latest version (the one with the highest number and get its directory back
The second thing you can try is checking the Directory.GetLastWriteTime(String), which you can compare, and find the last one, please not that this is not reliable at all since the folder can be changed by anything.
I need some advice regarding the use of a command line utility from a C#/ASP.NET web application.
I found a 3rd party utility for converting files to CSV format. The utility works perfectly and it can be used from the command line.
I have been looking on the web for examples on how to execute the command line utility and found this example.
The problem is this is not very good. When I try to us the example code with my utility, I get a prompt asking me to install the utility on the client machine. This is not what I want. I do not want the user to see what is going on in the background.
Is it possible to execute the command server side and processing the file from there?
Any help would be greatly appreciated.
I've done something like this several times in the past, and here's what's worked for me:
Create an IHttpHandler implementation (easiest to do as an .ashx file) to handle a convert. Within the handler, use System.Diagnostics.Process and ProcessStartInfo to run your command line utility. You should be able to redirect the standard output to the output stream of your HTTP response. Here's some code:
public class ConvertHandler : IHttpHandler
{
#region IHttpHandler Members
bool IHttpHandler.IsReusable
{
get { return false; }
}
void IHttpHandler.ProcessRequest(HttpContext context)
{
var jobID = Guid.NewGuid();
// retrieve the posted csv file
var csvFile = context.Request.Files["csv"];
// save the file to disk so the CMD line util can access it
var filePath = Path.Combine("csv", String.Format("{0:n}.csv", jobID));
csvFile.SaveAs(filePath);
var psi = new ProcessStartInfo("mycsvutil.exe", String.Format("-file {0}", filePath))
{
WorkingDirectory = Environment.CurrentDirectory,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
using (var process = new Process { StartInfo = psi })
{
// delegate for writing the process output to the response output
Action<Object, DataReceivedEventArgs> dataReceived = ((sender, e) =>
{
if (e.Data != null) // sometimes a random event is received with null data, not sure why - I prefer to leave it out
{
context.Response.Write(e.Data);
context.Response.Write(Environment.NewLine);
context.Response.Flush();
}
});
process.OutputDataReceived += new DataReceivedEventHandler(dataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(dataReceived);
// use text/plain so line breaks and any other whitespace formatting is preserved
context.Response.ContentType = "text/plain";
// start the process and start reading the standard and error outputs
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
// wait for the process to exit
process.WaitForExit();
// an exit code other than 0 generally means an error
if (process.ExitCode != 0)
{
context.Response.StatusCode = 500;
}
}
}
#endregion
}
The command is running server side. Any code is running on the server. The code in the example that you give works. You just need to make sure that the utility is set up properly on the server and that you have permissions to the directory/file.
I am designing a small C# application and there is a web browser in it. I currently have all of my defaults on my computer say google chrome is my default browser, yet when I click a link in my application to open in a new window, it opens internet explorer. Is there any way to make these links open in the default browser instead? Or is there something wrong on my computer?
My problem is that I have a webbrowser in the application, so say you go to google and type in "stack overflow" and right click the first link and click "Open in new window" it opens in IE instead of Chrome. Is this something I have coded improperly, or is there a setting not correct on my computer
===EDIT===
This is really annoying. I am already aware that the browser is IE, but I had it working fine before. When I clicked a link it opened in chrome. I was using sharp develop to make the application at that time because I could not get c# express to start up. I did a fresh windows install and since I wasn't too far along in my application, I decided to start over, and now I am having this problem. That is why I am not sure if it is my computer or not. Why would IE start up the whole browser when a link is clicked rather than simply opening the new link in the default browser?
You can just write
System.Diagnostics.Process.Start("http://google.com");
EDIT: The WebBrowser control is an embedded copy of IE.
Therefore, any links inside of it will open in IE.
To change this behavior, you can handle the Navigating event.
For those finding this question in dotnet core. I found a solution here
Code:
private void OpenUrl(string url)
{
try
{
Process.Start(url);
}
catch
{
// hack because of this: https://github.com/dotnet/corefx/issues/10361
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
url = url.Replace("&", "^&");
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Process.Start("xdg-open", url);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
Process.Start("open", url);
}
else
{
throw;
}
}
}
After researching a lot I feel most of the given answer will not work with dotnet core.
1.System.Diagnostics.Process.Start("http://google.com"); -- Will not work with dotnet core
2.It will work but it will block the new window opening in case default browser is chrome
myProcess.StartInfo.UseShellExecute = true;
myProcess.StartInfo.FileName = "http://some.domain.tld/bla";
myProcess.Start();
Below is the simplest and will work in all the scenarios.
Process.Start("explorer", url);
public static void GoToSite(string url)
{
System.Diagnostics.Process.Start(url);
}
that should solve your problem
Did you try Processas mentioned here: http://msdn.microsoft.com/de-de/library/system.diagnostics.process.aspx?
You could use
Process myProcess = new Process();
try
{
// true is the default, but it is important not to set it to false
myProcess.StartInfo.UseShellExecute = true;
myProcess.StartInfo.FileName = "http://some.domain.tld/bla";
myProcess.Start();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
My default browser is Google Chrome and the accepted answer is giving the following error:
The system cannot find the file specified.
I solved the problem and managed to open an URL with the default browser by using this code:
System.Diagnostics.Process.Start("explorer.exe", "http://google.com");
I'm using this in .NET 5, on Windows, with Windows Forms. It works even with other default browsers (such as Firefox):
Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true });
Based on this and this.
Try this , old school way ;)
public static void openit(string x)
{
System.Diagnostics.Process.Start("cmd", "/C start" + " " + x);
}
using : openit("www.google.com");
Am I the only one too scared to call System.Diagnostics.Process.Start() on a string I just read off the internet?
public bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
{
Request = request;
string url = Request.Url;
if (Request.TransitionType != TransitionType.LinkClicked)
{ // We are only changing the behavoir when someone clicks on a link.
// Let the embedded browser handle this request itself.
return false;
}
else
{ // The user clicked on a link. Something like a filter icon, which links to the help for that filter.
// We open a new window for that request. This window cannot change. It is running a JavaScript
// application that is talking with the C# main program.
Uri uri = new Uri(url);
try
{
switch (uri.Scheme)
{
case "http":
case "https":
{ // Stack overflow says that this next line is *the* way to open a URL in the
// default browser. I don't trust it. Seems like a potential security
// flaw to read a string from the network then run it from the shell. This
// way I'm at least verifying that it is an http request and will start a
// browser. The Uri object will also verify and sanitize the URL.
System.Diagnostics.Process.Start(uri.ToString());
break;
}
case "showdevtools":
{
WebBrowser.ShowDevTools();
break;
}
}
}
catch { }
// Tell the browser to cancel the navigation.
return true;
}
}
This code was designed to work with CefSharp, but should be easy to adapt.
Take a look at the GeckoFX control.
GeckoFX is an open-source component
which makes it easy to embed Mozilla
Gecko (Firefox) into any .NET Windows
Forms application. Written in clean,
fully commented C#, GeckoFX is the
perfect replacement for the default
Internet Explorer-based WebBrowser
control.
dotnet core throws an error if we use Process.Start(URL). The following code will work in dotnet core. You can add any browser instead of Chrome.
var processes = Process.GetProcessesByName("Chrome");
var path = processes.FirstOrDefault()?.MainModule?.FileName;
Process.Start(path, url);
This opened the default for me:
System.Diagnostics.Process.Start(e.LinkText.ToString());
I tried
System.Diagnostics.Process.Start("https://google.com");
which works for most of the cases but I run into an issue having a url which points to a file:
The system cannot find the file specified.
So, I tried this solution, which is working with a little modification:
System.Diagnostics.Process.Start("explorer.exe", $"\"{uri}\"");
Without wrapping the url with "", the explorer opens your document folder.
In UWP:
await Launcher.LaunchUriAsync(new Uri("http://google.com"));
Open dynamically
string addres= "Print/" + Id + ".htm";
System.Diagnostics.Process.Start(Path.Combine(Environment.CurrentDirectory, addres));
update the registry with current version of explorer
#"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION"
public enum BrowserEmulationVersion
{
Default = 0,
Version7 = 7000,
Version8 = 8000,
Version8Standards = 8888,
Version9 = 9000,
Version9Standards = 9999,
Version10 = 10000,
Version10Standards = 10001,
Version11 = 11000,
Version11Edge = 11001
}
key.SetValue(programName, (int)browserEmulationVersion, RegistryValueKind.DWord);
This works nicely for .NET 5 (Windows):
ProcessStartInfo psi = new ProcessStartInfo {
FileName = "cmd.exe",
Arguments = $ "/C start https://stackoverflow.com/",
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true
};
Process.Start(psi);
to fix problem with Net 6
i used this code from ChromeLauncher
,default browser will be like it
internal static class ChromeLauncher
{
private const string ChromeAppKey = #"\Software\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe";
private static string ChromeAppFileName
{
get
{
return (string) (Registry.GetValue("HKEY_LOCAL_MACHINE" + ChromeAppKey, "", null) ??
Registry.GetValue("HKEY_CURRENT_USER" + ChromeAppKey, "", null));
}
}
public static void OpenLink(string url)
{
string chromeAppFileName = ChromeAppFileName;
if (string.IsNullOrEmpty(chromeAppFileName))
{
throw new Exception("Could not find chrome.exe!");
}
Process.Start(chromeAppFileName, url);
}
}
I'd comment on one of the above answers, but I don't yet have the rep.
System.Diagnostics.Process.Start("explorer", "stackoverflow.com");
nearly works, unless the url has a query-string, in which case this code just opens a file explorer window. The key does seem to be the UseShellExecute flag, as given in Alex Vang's answer above (modulo other comments about launching random strings in web browsers).
You can open a link in default browser using cmd command start <link>, this method works for every language that has a function to execute a system command on cmd.exe.
This is the method I use for .NET 6 to execute a system command with redirecting the output & input, also pretty sure it will work on .NET 5 with some modifications.
using System.Diagnostics.Process cmd = new();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.WriteLine("start https://google.com");
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
I have ASP.NET web pages for which I want to build automated tests (using WatiN & MBUnit). How do I start the ASP.Net Development Server from my code? I do not want to use IIS.
This is what I used that worked:
using System;
using System.Diagnostics;
using System.Web;
...
// settings
string PortNumber = "1162"; // arbitrary unused port #
string LocalHostUrl = string.Format("http://localhost:{0}", PortNumber);
string PhysicalPath = Environment.CurrentDirectory // the path of compiled web app
string VirtualPath = "";
string RootUrl = LocalHostUrl + VirtualPath;
// create a new process to start the ASP.NET Development Server
Process process = new Process();
/// configure the web server
process.StartInfo.FileName = HttpRuntime.ClrInstallDirectory + "WebDev.WebServer.exe";
process.StartInfo.Arguments = string.Format("/port:{0} /path:\"{1}\" /virtual:\"{2}\"", PortNumber, PhysicalPath, VirtualPath);
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
// start the web server
process.Start();
// rest of code...
From what I know, you can fire up the dev server from the command prompt with the following path/syntax:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Webdev.WebServer.exe /port:[PORT NUMBER] /path: [PATH TO ROOT]
...so I could imagine you could easily use Process.Start() to launch the particulars you need through some code.
Naturally you'll want to adjust that version number to whatever is most recent/desired for you.
Building upon #Ray Vega's useful answer, and #James McLachlan's important update for VS2010, here is my implementation to cover VS2012 and fallback to VS2010 if necessary. I also chose not to select only on Environment.Is64BitOperatingSystem because it went awry on my system. That is, I have a 64-bit system but the web server was in the 32-bit folder. My code therefore looks first for the 64-bit folder and falls back to the 32-bit one if necessary.
public void LaunchWebServer(string appWebDir)
{
var PortNumber = "1162"; // arbitrary unused port #
var LocalHostUrl = string.Format("http://localhost:{0}", PortNumber);
var VirtualPath = "/";
var exePath = FindLatestWebServer();
var process = new Process
{
StartInfo =
{
FileName = exePath,
Arguments = string.Format(
"/port:{0} /nodirlist /path:\"{1}\" /virtual:\"{2}\"",
PortNumber, appWebDir, VirtualPath),
CreateNoWindow = true,
UseShellExecute = false
}
};
process.Start();
}
private string FindLatestWebServer()
{
var exeCandidates = new List<string>
{
BuildCandidatePaths(11, true), // vs2012
BuildCandidatePaths(11, false),
BuildCandidatePaths(10, true), // vs2010
BuildCandidatePaths(10, false)
};
return exeCandidates.Where(f => File.Exists(f)).FirstOrDefault();
}
private string BuildCandidatePaths(int versionNumber, bool isX64)
{
return Path.Combine(
Environment.GetFolderPath(isX64
? Environment.SpecialFolder.CommonProgramFiles
: Environment.SpecialFolder.CommonProgramFilesX86),
string.Format(
#"microsoft shared\DevServer\{0}.0\WebDev.WebServer40.EXE",
versionNumber));
}
I am hoping that an informed reader might be able to supply the appropriate incantation for VS2013, as it apparently uses yet a different scheme...
You can easily use Process Explorer to find complete command line options needed for manually start it.
Start Process Explorer while debugging your website. For VS2012, expand 'devenv.exe' node. Right-click on 'WebDev.WebServer20.exe' and from there you can see Path and Command Line values.