I've been looking into this for awhile now as I have created a client I would love to be able to run in a separate window (In a similar design to the Blizzard launcher or the old Ijji reactor). I was wondering if this was possible. Last week I created a web browser within Visual Basic but I was not happy with the final result at the bars where still stationed around the window. Any helpful tips or advice would be appreciated!
You didn't specify language, so you get it in c#. This might work. Starts chrome in app mode. here is the argument list
http://peter.sh/experiments/chromium-command-line-switches/
url = "--app=http://google.com";
Process[] pname = Process.GetProcessesByName("chrome");
if (pname.Length == 0)
{
chrome = false;
}
else // if chrome is running
{
if (!chrome)
{
Process process = new Process();
process.StartInfo.FileName = "chrome";
process.StartInfo.Arguments = url;
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
//Process.Start("chrome", url);
}
chrome = true;
}
Related
My code (below) using a foreach loop for multiple urls and save screen shots of each url). This code works perfectly in my dev environment ( Visual studio 2010, Windows 7 64 bit).I can take screen shots of url and save it in a folder. But the same code I deployed in a server (Windows server 2003, IIS- 6.0), it is not saving screen shots for some url. I captured the logs and it says System.Threading.ThreadAbortException: Thread was being aborted.System.Threading.Thread.JoinInternal().
Is it works with IIS 6.0 or any other settings has to do with the deployment server? It works perfectly in my local environment. Any help appreciated.
public void Capture(string url, string path)
{
_path = path;
var thread = new Thread(() =>
{
using (var browser = new WebBrowser())
{
browser.ScrollBarsEnabled = false;
browser.AllowNavigation = true;
browser.Navigate(url);
browser.Width = 1600;
browser.Height = 1600;
browser.ScriptErrorsSuppressed = true;
browser.DocumentCompleted += DocumentCompleted;
while (browser.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
I have this console app that another application starts. This is what I'm playing around with to start it:
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.FileName = #"C:\...\MyApp.exe";
processStartInfo.Arguments = "a, a, \\n, d, c";
processStartInfo.CreateNoWindow = true;
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
Process process = Process.Start(processStartInfo);
The idea behind this Console App, is that after it runs through these arguments, the only thing visible to the User is a SysTray Icon they can interact with. One of the options is the ability to Show the console. This is a two-fold question:
Since the Console App is started in the background, how do I get it to no longer be in the background? Originally I was using some ShowWindow/HideWindow approach using some COM and P/Invoke, but this seems to be different.
When this Process code is run, the Console App briefly flashes then goes to the background. How can I suppress this flash of the Console? That doesn't look professional at all.
I'm having a very frustrating problem. I have a c# win application. When I have clicked the button, the program closes itself after executed the click event handler. Even if I have debugged the code unfortunately I can't see any error, It just quits the program.
Where am I going wrong?
Here is the Code:
private void btnOpenFolder_Click(object sender, EventArgs e)
{
DialogResult dg = fd1.ShowDialog();
if (dg == DialogResult.OK)
{
lblInput.Text = fd1.SelectedPath;
btnOpenFolder.Enabled = false;
timerCallback = new TimerCallback(tmrQualityEvent);
tmrQuality = new System.Threading.Timer(timerCallback, null, 0, 1000);
Thread qualityThread = new Thread(new ThreadStart(QualityMapOpenFolder));
qualityThread.Start();
QualityMapOpenFolder();
}
}
void QualityMapOpenFolder()
{
fileList.Clear();
string path = lblInput.Text;
if (Directory.Exists(path))
{
foreach (var file in Directory.GetFiles(path))
{
if (Path.GetExtension(file) != ".kml")
{
fileList.Add(file);
}
}
SetProgressBarValue(0);
ChangeFileNameLabel(fileList[0]);
FileName = fileList[0];
}
else
SetText("Please make sure you have correctly set the open folder path!", true);
dataListQuality = GetInputData();
SetText("Calculated Data has been created, please click process files...", false);
SetProcessButtonStatus(true);
}
Attach an event handler to the UnhandledException handler and log it. Should help you to find out why your application is crashing.
Update: Now that you have posted some code:
You seem to update UI elements from another thread which you start. You should access UI components only from the thread on which they were created (usually the main thread). Consider using a BackgroundWorker
You start the QualityMapOpenFolder method on a thread and then you also call it after you started the thread - this seems a bit weird and has probably some unexpected side effects.
The common reason for this kind of behavior is unhandled exception in background thread. To prevent program.
#ChrisWue wrote on how to detect this kind of exceptions.
Also, often Windows Application log provides an insight on unhandled errors.
See here how to prevent killing app in this case.
I'm hoping someone can help me with this. I have found the examples for recording audio using XNA in a Silverlight application. And it works, however, only the first time in. I have all the recording functionality on a seperate WP7 Page and with successive visits to the page it doesn't work. The best I can tell is the microphone.start is getting called but the micophone.status remains stopped. What is weird is the BufferReady keeps getting called and the code within that function is all running but without the microphone really starting nothing is really happening. When you exit the app and come back in again the first time visit to the page and everything works fine, but a revisit to the page and it doesn't.
void microphone_BufferReady(object sender, EventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
microphone.GetData(buffer);
stream.Write(buffer, 0, buffer.Length);
TimeSpan tsTemp = timer.Elapsed;
TextBlockSeconds.Text = tsTemp.Hours.ToString().PadLeft(2, '0') + ":" + tsTemp.Minutes.ToString().PadLeft(2, '0') + ":" + tsTemp.Seconds.ToString().PadLeft(2, '0');
if(timer.Elapsed.Seconds >5)
DoStop();
});
}
private void ButtonRecord_Click(object sender, RoutedEventArgs e)
{
DisableRecordButton();
timer = new Stopwatch();
timer.Start();
stream = new MemoryStream();
TextBlockSeconds.Text = "00:00:00";
TextBlockStatus.Text = "Recording: ";
microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
buffer = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];
microphone.BufferReady += new EventHandler<EventArgs>(microphone_BufferReady);
microphone.Start();
}
private void DoStop()
{
if (timer.IsRunning)
timer.Stop();
if (microphone.State == MicrophoneState.Started)
{
microphone.Stop();
TextBlockStatus.Text = "Stopped: Ready to save";
}
else
{
TextBlockStatus.Text = "Ready: ";
}
TextBlockSeconds.Text = string.Empty;
EnableRecordButton();
}
Update...
I found the problem but no solution. I was calling the microphone.stop via code on a timer (so I could limit the recorded audio to 5 seconds). Exact same code to execute when a manual stop button would be clicked. When clicking the manual stop button everything worked fine, could re-visit the page and all would be fine. When the stop was called in code from the timer, next visit to the page would not work. So I implemented it with only a manual stop button but really would have been nice to do it automatically (and to know what the real issue was).
actually when you are navigating away from the page you can add
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
this.MicroPhone.BufferReady -= this.Microphone_BufferReady;
}
and when you are returning to page add
this.MicroPhone.BufferReady += this.Microphone_BufferReady;
You can add this statement either in a page loaded event or an OnNavigatedTo event
Added string name = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() to make sure that it was on the same thread (and it was).
But finally worked this out, the problem is the microphone.stop doesn't stop the microphone from continuing to fire the buffer ready event (like I was expecting). And it would seem the way the page is cached this causes some weird problems with that event still firing. So I added the code
microphone.BufferReady -= new EventHandler<EventArgs>(microphone_BufferReady);
to my code for stopping, and it all works now.
I can't see from your code how you're stopping the timer/microphone if you navigate away from the page and don't manually stop it.
If that's not it, are you ensuring that all your microphone operations are being executed on the same thread? (Just a thought.)
I'm trying to use FireWatir (1.6.5) to access a site using Basic
Authentication and I've been unable to find a solution that works on
Firefox in Linux. Does FireWatir 1.6.5 support Basic Authentication
on Linux? I've been searching the web for 2 days and can't get a
straight answer anywhere as to how to do this.
The only thread I found that seemed helpful was this one (
http://groups.google.com/group/watir-general/browse_thread/thread/d8ab9a177d282ce4/fc1bf2319fb387d8?lnk=gst&q=basic+authentication#fc1bf2319fb387d8).
Aedorn Varanis says " Angrez's fork had the solution so I'm using that
now. Thanks Angrez, works perfectly!", but he doesn't mention what he
did to get things working.
Initially I tried to bypass the authentication dialog box by using:
browser.goto('http://admin:password#172.20.1.1')
However, this generates a "Confirm" dialog which says:
"You are about to log in to the site "172.20.1.1" with the username
"admin"." [Cancel, OK]
This dialog blocks, and the goto call won't return until I click "OK".
Then I tried adding:
browser.startClicker("ok")
browser.goto('http://admin:password#172.20.1.1')
But this ALSO generates the same "Confirm" dialog.
I tested out the startClicker functionality using the unit test /var/
lib/gems/1.8/gems/firewatir-1.6.5/unittests/html/JavascriptClick.html
and it worked fine, which makes me think that using the startClicker
method is NOT the correct way to take care of the Confirm dialog.
Anybody else found a way to get Basic Auth to work, or how to click
the OK on the confirm dialog? I'm at my wits end...
This may be a long ugly workaround, and may also violate the simplicity of watir's philosophy, but since you are at your wits end ...
1) Sahi (http://sahi.co.in/) handles 401 authentication dialogs by converting them into regular web pages.
2) Sahi's proxy needs to be running, and you point your browser to use Sahi's proxy.
3) You can then navigate to your page and just use watir/firewatir to enter username password into a converted 401 authentication web page, (like a regular form).
You would incur the extra load of the proxy, but Sahi is fairly well behaved so you should be able to make it work.
You could post here or on Sahi's forums if you need further assistance.
Hope that helps.
-Narayan
With help from Aedorn Varanis I've got things working on Firefox in
Linux.
Aedorn sent me a "logon" method which issues a jssh command that
checks for an "Authentication Required" dialog and if it exists, fills
in the username/password and submits the dialog.
I've copied and pasted what he sent me below:
You use a method that looks like this:
def logon(username, password, wait=3)
jssh_command = "var length = getWindows().length; var win;var found=false; for(var i = 0; i < length; i++) { win = getWindows()[i]; if(win.document.title == \"Authentication Required\") { found = true; break; }} if(found) { var jsdocument = win.document; var dialog = jsdocument.getElementsByTagName(\"dialog\")[0];"
jssh_command << " jsdocument.getElementsByTagName(\"textbox\")[0].value = \"#{username}\";"
jssh_command << " jsdocument.getElementsByTagName(\"textbox\")[1].value = \"#{password}\";"
jssh_command << " dialog.getButton(\"accept\").click(); }\n"
sleep(wait)
$jssh_socket.send(jssh_command,0)
read_socket()
wait()
end
Then you can call it within its own
thread just before going to the site
with the login requirement:
Thread.new { logon(user, pass) }
#ff.goto("http://some_url.com")
sleep 3
Increase the wait and sleep time if
the page takes awhile to load. If your
main process tries to run while the
command is being sent through the JSSH
socket, it will stall and sit there
forever until killed. Also, there's no
real way to detect if the
authentication window comes up. That
means you need to make sure it always
works the same way every time, or it,
too, causes problems. Finally, the
method will always have to be in
another thread, because once the
authentication window comes up, it
stops all other processing until it
goes away. Other than that, it works.
From this, I was able to subclass the FireWatir::Firefox class with a
new Browser class which supports a "credentials=" method just like the
Celerity::Browser does. So, just like using celerity, you can do:
require 'browser'
browser = Browser.new
browser.credentials = 'user:pass'
browser.goto('http://some.basic.auth.url')
This will automatically fill in the Basic Auth dialog and log you into
the site.
I've posted the contents of my browser.rb file below (notice this
works in ruby+firewatir and jruby+celerity in linux):
ENGINE = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
if ENGINE == 'ruby'
require 'firewatir'
class Browser < FireWatir::Firefox
def initialize(options={})
super(options)
#username = nil
#password = nil
end
def credentials=(string)
username, password = string.split(":")
if username.nil? or password.nil?
raise "Invalid credentials: #{string})"
else
#username = username
#password = password
end
end
def goto(url, wait=3)
if #username.nil? and #password.nil?
return super(url)
else
t = Thread.new { logon(#username, #password, wait) }
result = super(url)
t.join
return result
end
end
private
def logon(username, password, wait)
jssh_command = "
var length = getWindows().length;
var win;
var found = false;
for (var i = 0; i < length; i++) {
win = getWindows()[i];
if(win.document.title == \"Authentication Required\") {
found = true;
break;
}
}
if (found) {
var jsdocument = win.document;
var dialog = jsdocument.getElementsByTagName(\"dialog\")[0];
jsdocument.getElementsByTagName(\"textbox\")[0].value = \"#{username}\";
jsdocument.getElementsByTagName(\"textbox\")[1].value = \"#{password}\";
dialog.getButton(\"accept\").click();
}
\n"
sleep(wait)
$jssh_socket.send(jssh_command,0)
read_socket()
end
end
elsif ENGINE == 'jruby'
require 'celerity'
class Browser < Celerity::Browser; end
else
raise "Ruby ENGINE '#{ENGINE}' not supported."
end
I battled long and hard with this issue until today. Apparently i overlooked the answer many times because it didn't look plausible. However, the solution lies in Firefox's "network.http.phishy-userpass-length" profile configuration. If FireWatir allows you to modify your firefox instance Profile, then you can give the "network.http.phishy-userpass-length" a value of 255 which should make that dialog disappear. check http://kb.mozillazine.org/Network.http.phishy-userpass-length for more details.
Note: With Capybara + selenium-webdriver in Ruby, I did;
require 'capybara'
require 'selenium-webdriver'
profile = Selenium::WebDriver::Firefox::Profile.new
profile['network.http.phishy-userpass-length'] = 255
Capybara::Selenium::Driver.new(:profile => profile, :browser => :firefox)