Hiding "preparation to install" window programatically - c#

Can we hide window populated due to following code,
IntPtr updatedHandle = new IntPtr();
UInt32 openVal = MsiInteract.MsiOpenPackage("C:\\MSIGet.MSI", out updatedHandle); //get handle for the MSI
I have one C# application that read some information from .MSI file for that i used above code. Which work great for me but one window get populated on MsiOpenPackage function call.As this function is in loop so it is fustrated for me when multiple window gets open.Please provide me any way to hide "preparation to install" window on function call MsiOpenPackage .

To suppress the UI shown when opening a package, you need to call MsiSetInternalUI or, if you wanted to show something else instead, MsiSetExternalUI. However if all you're doing is reading information from the Property table or Summary Information Stream, you can just call MsiOpenDatabase instead of MsiOpenPackage as that will not begin an installation session and thus will not show UI.

Using the quiet installer You can avoid any window opening for user confirmation or dialog.
string installer = _installer;
System.Diagnostics.Process FProcess = new System.Diagnostics.Process();
FProcess.StartInfo.FileName = "MsiExec.exe";
FProcess.StartInfo.Arguments = "/quiet /i " + installer;
FProcess.StartInfo.UseShellExecute = false;
FProcess.Start();
FProcess.WaitForExit();

Related

Can't send keys (string) to notepad

I thought that code is pretty good, bu it isn't. I'm trying to add something text to my notepad, which look like:
string text = "TESTTESTTESTTEST";
[DllImport("user32.dll")]
private static extern int SetForegroundWindow(IntPtr hWnd);
public void EditTxtFile(string text)
{
Process p = Process.GetProcessesByName("notepad").FirstOrDefault();
if (p != null)
{
IntPtr handle = p.MainWindowHandle;
SetForegroundWindow(handle);
SendKeys.SendWait(text);
p.Kill(); //also process doesn't shoutdown
}
}
When i try to debug this function (actually SendKeys), that message is showing up:
Changes are not allowed while code is runnig.
If it's important i try to edit this from web page/application.
The problem is, that Visual Studio catches Focus when it hits the break point, and then SendKeys is send to Visual Studio instead of notepad, and this produces the error.
What you can do ist the following:
Right Click on the Breakpoint and select "When Hit..."
There you can output whatever you want without Notepad losing Focus
Problem was in function which was responsible for opening that notepad (not enough time to start and open him). I've just add wait function for 4s.
To mine, it's about I use a reference value text from the source WinForms's control, call SendKeys' function while the source form is not yet close or hide before (still the active form). This can produce a similar result: SendKeys.Send() or SendKeys.SendWait() does not send a desired text to the target application.
The steps to workaround this:
1. transfer the text value from the active form to a new temporary variation or a Clipboard,
2. close or hide the active form,
3. activate the target application's form,
4. wait a bit to ensure the target application's form to become active 5. and give the temporary text variation or Clipboard to SendKeys. Works.
PS: Please make sure your application has runtime permission equals or more than the target application.

Clicking a button on a windows from from a webform

I have created a windows form program that does some Business Intelligence but have subsequently needed to access this via a webform. I am fairly new to programming so I don't know what can be achieved here. But essentially I am wanting someone to go on to the net and when the user presses a button it sends a message to the windows form executable in a file and tells it to run and then press a button on the form, which runs a method to generate images of graphs. Is this possible?
Here is the relevant code.
In the webform I have this button.
protected void rolloutSmartSheets(object sender, EventArgs e)
{
string message = string.Format("Starting processes");
ltMessage.Text = message;
Process process = new Process();
process.StartInfo.FileName = #"P:\Visual Studio 2013\Projects\Smartsheet\SmartsheetAPI\obj\Debug\SmartSheetAPI.exe";
process.Start();
message = string.Format("Ended all processes");
ltMessage.Text = message;
}
That runs the executable but it opens the windows form and I imagine if the executable is sitting on another computer wouldn't that open on that computer? In which case i want it to tell it to press this button on the windows form which runs the method I need and then the user doesn't need to worry about it.
public void commitToDatabase_Click(object sender, EventArgs e)
{
commitToDataBase();
}
If you are able to have the clients install something in advance, you can provide this functionality using a custom protocol handler.
Example protocol handler from MSDN Article
HKEY_CLASSES_ROOT
alert
(Default) = "URL:Alert Protocol"
URL Protocol = ""
DefaultIcon
(Default) = "alert.exe,1"
shell
open
command
(Default) = "C:\Program Files\Alert\alert.exe" "%1"
Then add a link onto your webform like this
href="alert://test"
As long as the client has the handler installed, both in the registry and the executable file, it will run C:\Program Files\Alert\alert.exe, passing "test" to it as the first paramater.
You can easily change this to provide the ability to run the local graph generator, and pass any parameters from the webform you might need.

How can I open an Excel file from C#/WPF in "Full Screen"?

Currently I'm opening files from my C#/WPF application using
System.Diagnostics.Process.Start("C:\ .... ");
Whether the application window is in full screen etc depends on the state the previous instance of the application was in when it was closed (e.g. If it was closed when full screen, it opens a new instance full screen)
What I'm trying to do is open a file in Excel and make it full screen. I looked into command line switches for Excel, seemed fairly limited since I can't modify the excel files by adding Application.DisplayFullScreen = True into a VBA module.
Edit: Was unclear, but I meant to open it in Full Screen mode (no ribbon etc), not maximized.
Edit2: The key sequence would be alt+v,u. Looking for a way to use SendKeys to send the key sequence to the excel window
Looks like you can use SendKeys.
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx
Edit: This code worked for me
Be sure to #include System.Windows.Forms and everything else that's needed.
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public void Go()
{
Process excel = new Process();
excel.StartInfo.FileName = #"C:\Test.xlsx";
excel.Start();
// Need to wait for excel to start
excel.WaitForInputIdle();
IntPtr p = excel.MainWindowHandle;
ShowWindow(p, 1);
SendKeys.SendWait("%(vu)");
}
See this SO post:
How to open a PDF file by using Foxit/Adobe in full screen mode?
Excel interop might work for you... it's rather nasty to code with but you can do pretty much anything with it that the user can do in excel itself.
This is an overview of how to use it
http://www.dotnetperls.com/excel
This says you can use the property Application.DisplayFullScreen to get it to go full screen
http://msdn.microsoft.com/en-us/library/office/aa168292(v=office.11).aspx

Getting output from one executable in an other one

I'm currently trying to get the output of an executable console-app into an other one. To be exact, a little overview of what I'm trying to do:
I have one executable which I cannot edit and neither see it's code. It writes some (quite a bunch to be honest) lines into the console when executed.
Now I want to write another executable that starts the one above and reads the things it writes.
Seems simple to me, so I started coding but ended up with an error message saying that StandardOut has not been redirected or the process hasn't started yet.
I tried it using this kinda structure (C#):
Process MyApp = Process.Start(#"C:\some\dirs\foo.exe", "someargs");
MyApp.Start();
StreamReader _Out = MyApp.StandardOutput;
string _Line = "";
while ((_Line = _Out.ReadLine()) != null)
Console.WriteLine("Read: " + _Line);
MyApp.Close();
I can open the executable and it also does open the one inside, but as soon as it comes to reading the returned values, the app crashes.
What am I doing wrong?!
Take a look at the documentation for the Process.StandardOutput property. You will need to set a boolean indicating that you want the stream redirected as well as disabling shell execute.
Note from the documentation:
To use StandardOutput, you must set ProcessStartInfo..::.UseShellExecute to false, and you must set ProcessStartInfo..::.RedirectStandardOutput to true. Otherwise, reading from the StandardOutput stream throws an exception
You would need to change your code a little bit to adjust for the changes:
Process myApp = new Process(#"C:\some\dirs\foo.exe", "someargs");
myApp.StartInfo.UseShellExecute = false;
myApp.StartInfo.RedirectStandardOutput = false;
myApp.Start();
string output = myApp.StandardOutput.ReadToEnd();
p.WaitForExit();
you could try setting processStartInfo.RedirectStandardOutput = true;
As noted above, you can use RedirectStandardOutput as here.
Another, dirtier way is something like
using (Process child = Process.Start
("cmd", #"/c C:\some\dirs\foo.exe someargs > somefilename"))
{
exeProcess.WaitForExit();
}
And then read its output from somefilename

How to use Process.Start() or equivalent with Mono on a Mac and pass in arguments

I am trying to write some c# code to start a browser using Process.Start(app,args); where apps is the path to the browser e.g. /Applications/Google Chrome.app/Contents/MacOS/Google Chrome and the args are --no-default-browser-check
If i do, which works on Windows and on Linux
Process.Start("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","--no-first-run");
I get
open: unrecognized option `--no-first-run'
Usage: open [-e] [-t] [-f] [-W] [-n] [-g] [-h] [-b <bundle identifier>] [-a <application>] [filenames]
Help: Open opens files from a shell.
By default, opens each file using the default application for that file.
If the file is in the form of a URL, the file will be opened as a URL.
Options:
-a Opens with the specified application.
-b Opens with the specified application bundle identifier.
-e Opens with TextEdit.
-t Opens with default text editor.
-f Reads input from standard input and opens with TextEdit.
-W, --wait-apps Blocks until the used applications are closed (even if they were already running).
-n, --new Open a new instance of the application even if one is already running.
-g, --background Does not bring the application to the foreground.
-h, --header Searches header file locations for headers matching the given filenames, and opens them.
I have also tried Monobjc to try run the code with
// spin up the objective-c runtime
ObjectiveCRuntime.LoadFramework("Cocoa");
ObjectiveCRuntime.Initialize();
NSAutoreleasePool pool = new NSAutoreleasePool();
// Create our process
NSTask task = new NSTask();
NSPipe standardOut = new NSPipe();
task.StandardOutput = standardOut;
task.LaunchPath = #"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
// add some arguments
NSString argumentString = new NSString("--no-first-run");
NSArray arguments = NSArray.ArrayWithObject(argumentString);
task.Arguments = arguments;
// We should have liftoff
task.Launch();
// Parse the output and display it to the console
NSData output = standardOut.FileHandleForReading.ReadDataToEndOfFile;
NSString outString = new NSString(output,NSStringEncoding.NSUTF8StringEncoding);
Console.WriteLine(outString);
// Dipose our objects, gotta love reference counting
pool.Release();
But when I run my code using NUnit it causes NUnit to blow up.
I suspect that this is a bug but can't prove it. I appreciate any and all help!
To make Process.Start use exec directly instead of using the OS' mechanism for opening files, you must set UseShellExecute to false. This is also true on Linux and Windows.
Process.Start(new ProcessStartInfo (
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"--no-first-run")
{ UseShellExecute = false });
Note that you can also use 'open' for your use case, to run the Chrome app bundle properly. Use the '-a' argument to force it to run a specific app, the '-n' argument to open a new instance, and '--args' to pass in arguments:
Process.Start(new ProcessStartInfo (
"open",
"-a '/Applications/Google Chrome.app' -n --args --no-first-run")
{ UseShellExecute = false });
Looks like Process uses the open command line utility to launch.
You should avoid calling the executable directly. If the application is already running, this would launch a second instance of it instead of activating the already running instance. That's probably not what you want, and not all applications can handle this anyway.
With open, the syntax to launch Chrome would be
open -a Chrome
I don't know how the Process class works on MacOS X, but I assume that the parameters should be similar.
Note, if you just want to open a web page, you should not specify the executable; instead, just pass the URL, so that it will be opened in the user's default browser. This is valid for any platform.
Process.Start("http://www.google.com");
Have you tried something like concatenating the parameters into the process name instead of passing it separated?
var processName = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
var args = "--no-default-browser-check";
Process.Start(String.Format("{0} {1}", processName, args));
Why dont you try something like this:
Process P = new Process();
P.StartInfo.FileName = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
P.StartInfo.Arguments = "--no-default-browser-check";
P.UseShellExecute = false;
P.Start();

Categories