ClickOnce + Restart = Opens Browser? - c#

I'm deploying a ClickOnce Application and want to restart the application after it was updated. Therefore I wrote following code:
private async void updateCheck()
{
using (var releaser = await _asyncLock.LockAsync())
{
UpdateCheckInfo info = null;
bool updateAvailable = false;
if (ApplicationDeployment.IsNetworkDeployed)
{
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
ad.UpdateCompleted += new System.ComponentModel.AsyncCompletedEventHandler(Ad_UpdateCompleted);
try
{
updateAvailable = ad.CheckForUpdate(false);
info = ad.CheckForDetailedUpdate();
}
catch (DeploymentDownloadException dde)
{
MessageBox.Show("The new version of the application cannot be downloaded at this time. \n\nPlease check your network connection, or try again later. Error: " + dde.Message);
return;
}
catch (InvalidDeploymentException ide)
{
MessageBox.Show("Cannot check for a new version of the application. The ClickOnce deployment is corrupt. Please redeploy the application and try again. Error: " + ide.Message);
return;
}
catch (InvalidOperationException ioe)
{
MessageBox.Show("This application cannot be updated. It is likely not a ClickOnce application. Error: " + ioe.Message);
return;
}
if (/*info.UpdateAvailable*/ updateAvailable)
{
Boolean doUpdate = true;
if (!info.IsUpdateRequired)
{
MessageBoxResult dr = MessageBox.Show("An update is available. Would you like to update the application now?", "Update Available", MessageBoxButton.OKCancel);
if (!(MessageBoxResult.OK == dr))
{
doUpdate = false;
}
}
else
{
// Display a message that the app MUST reboot. Display the minimum required version.
MessageBox.Show("This application has detected a mandatory update from your current " +
"version to version " + info.MinimumRequiredVersion.ToString() +
". The application will now install the update and restart.",
"Update Available", MessageBoxButton.OK,
MessageBoxImage.Information);
}
if (doUpdate)
{
try
{
//ad.Update();
ad.UpdateAsync();
}
catch (DeploymentDownloadException dde)
{
MessageBox.Show("Cannot install the latest version of the application. \n\nPlease check your network connection, or try again later. Error: " + dde);
return;
}
}
}
}
}
}
private void Ad_UpdateCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
if (e.Error == null)
{
MessageBox.Show("The application has been upgraded, and will now restart.");
String ApplicationEntryPoint = ApplicationDeployment.CurrentDeployment.UpdatedApplicationFullName;
Process.Start(ApplicationEntryPoint);
Application.Current.Shutdown();
}
}
Unfortunate in UpdatedApplicationFullName a URL to the Website where the deployment packages are stored. So Process.Start(ApplicationEntryPoint) opens a Browser Window and tries to download the package once again.
The behaviour I want is that the Process.Start(...) opens the new updated application.
Has anyone an idea what I'm doing wrong?
Thanks.

Related

C# - Using loop to open dialog box

I'm trying to make a program that loads a configuration file from another application.
If the file exists, it loads it and displays a message, but if the configuration file is not valid, it displays an error message and then opens a dialog box to load the correct file. But if the user reloads the wrong file, the same dialog box should appear again but that's when my code fails.
Similarly, if the file did not exist from the beginning, it displays a dialog box to load the file, but if it is given to cancel the dialog box or an incorrect file is selected again, my code fails.
I know that the solution would be to use loops but I'm not sure how to structure it.
Pd: searchfile() is my function to open dialog box and readconfig() is my function to read config file of another application.
strfilenamepath = #"C:\Users\test\dogs.exe.config";
if (File.Exists(strfilenamepath))
{
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
try
{
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
catch (Exception ex)
{
MessageBox.Show("Error loading config file." + ex.Message);
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
}
else
{
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
try
{
readConfig(strfilenamepath);
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
catch (Exception ex)
{
MessageBox.Show("Error loading config file." + ex.Message);
searchFile();
onlyFilename = System.IO.Path.GetFileName(strfilenamepath);
textBox1.Text = onlyFilename;
string[] valores = readConfig(strfilenamepath);
MessageBox.Show(valores[0] + valores[1] + valores[2]);
}
}
It is easier to design it if you extract the reading logic to another method that handles exceptions and returns a Boolean to signal the success and the computed result. The TryDoSomething pattern does exactly this.
In pseudo code
public bool TryReadConfig(string path, out string[] valores)
{
valores = null;
try {
valores = read the values;
return true;
} catch {
Display message;
return false;
}
}
The main loop in pseudo code
strfilenamepath = #"C:\Users\test\dogs.exe.config";
while (true) {
if (File.Exists(strfilenamepath) && TryReadConfig(strfilenamepath, out var valores)) {
Do something with the valores;
break;
}
var ofd = new OpenFileDialog{ ... };
if (ofd.ShowDialog() == DialogResult.OK) {
strfilenamepath = ofd.Filename;
} else {
break; // The user canceled the operation.
}
}
You can do something like this:
try
{
//Code to try open the file to memory
}
catch (Exception ex)
{
while (true)
{
MessageBox.Show(#"Select an valid file");
var path = searchFile();
if (string.IsNullOrWhiteSpace(path))
continue;
try
{
//Code to try open the file to memory
}
catch (Exception ex2)
{
MessageBox.Show(#"The selected file is not valid");
continue;
}
break;
}
}

My File accdb is missing but Data still can entry

In my C# apps "MyApps.Exe", i use Provider Microsoft.ace.oledb.12.0 to access my accdb file..
I set data source with
Data Source="+Application.StartupPath+"\\databaseFile.accdb
So my apps will read the databaseFile.accdb in the same folder with Exe file. The folder name is CurrentFolder.
I have compile my apps and install it in : "C:\Program Files(x86)\CurrentFolder"
Peculiarities occur, when file "databaseFile.accdb" has been deleted from folder "CurrentFolder".
When I run "MyApps.exe", then login entry username and password, and then Entry ,read data. The Apps is still running.
This should not happen because "databaseFile.accdb" has been deleted.
Why it can happen? I am confused for this happen.
Anyone can explain this ? why my Apss still can access/read database.accdb
eventough the database was deleted.
Thanks in advance.
--Addition Information --
Before, i share folder "C:\Program Files(x86)\CurrentFolder" to network. and add Permissions to Everyone Full Control.
I hope this information can help our problem analysis.
Here source code my connection.cs
public Connection()
{
try
{
alamat = "Provider=Microsoft.ace.Oledb.12.0; Data Source="+Application.StartupPath+"\\databaseFile.accdb";
koneksi = new OleDbConnection(alamat);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static Connection GetInstance(){
if(Connection.connection == null){
Connection.connection = new Connection();
}
return Connection.connection;
}
//this is for check wether the file databaseFile.accdb is exist in that folder
public int cekDb(string locasi)
{
int a=0;
if (File.Exists(locasi))
{
a = 1;
}
return a;
}
public int CekLogin(string user,string pass)
{
koneksi.Close();
koneksi.Open();
perintah = new OleDbCommand("select * from [user] where username = '" + user + "' and password = '" + pass + "';", koneksi);
myReader = perintah.ExecuteReader();
int count = 0;
while (myReader.Read())
{
leveluser = myReader["type"].ToString();
count++;
}
koneksi.Close();
return count;
}
In my login.cs
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" || textBox2.Text == "")
{
MessageBox.Show("Please Fill your Username or Password");
textBox1.Focus();
}
else
{
if(connection.cekDb(Application.StartupPath+"\\databaseFile.accdb")==1){
int cek = connection.CekLogin(textBox1.Text.Trim().Replace("'", "''"), textBox2.Text.Trim().Replace("'", "''"));
if (cek != 0)
{
DashBoard entry = new DashBoard();
entry.Show();
UseWaitCursor = false;
}
else if (cek == 0)
{
// konek.Disconnect();
MessageBox.Show("Please Check your username and password !!");
}
else
{
MessageBox.Show(cek.ToString());
}
}
else
{
MessageBox.Show("File DatabaseFile.accdb Not Found !!");
}
}
}

How To Tell If WCF Service Is Running At Host?

I have a C# application that is self hosting a WCF service. I want to add a button click event in the application that lets the user know if the service is running/being hosted. Is there a way to detect if the service is running/hosted?
In case someone wants to see it, here is the code I am using to start hosting the service:
private static void RunService()
{
System.ServiceModel.ServiceHost host = new System.ServiceModel.ServiceHost(typeof(AccountingOperationsService.AccountingOperationsService));
System.ServiceModel.Description.ServiceDebugBehavior debug = host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceDebugBehavior>();
// if not found - add behavior with setting turned on
if (debug == null)
{
host.Description.Behaviors.Add(
new System.ServiceModel.Description.ServiceDebugBehavior() { IncludeExceptionDetailInFaults = true });
}
else
{
// make sure setting is turned ON
if (!debug.IncludeExceptionDetailInFaults)
{
debug.IncludeExceptionDetailInFaults = true;
}
}
try
{
host.Open();
}
catch (Exception ex)
{
string errorMessage = ex.Message + Environment.NewLine;
errorMessage += ex.StackTrace + Environment.NewLine;
DevExpress.XtraEditors.XtraMessageBox.Show(errorMessage, "Error Starting Service", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Perhaps, you need create method Ping in wcf service.
public bool Ping()
{
return true;
}
and in application call Ping
bool itsWork;
try
{
itsWork = service.Ping();
}
catch(Exception ex){}

check the status of IIS Application Pool

I am developing a windows service which will gets the IIS Application Pool status information in every 5 min and stored in database or text file ... like running or stopped.
Getting below exception message:
An exception of type 'System.UnauthorizedAccessException' occurred in Microsoft.Web.Administration.dll but was not handled in user code Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
Below is the code I have tried:
static void Main(string[] args)
{
const double interval60Minutes = 5 * 5 * 1000; // milliseconds to one hour
Timer checkForTime = new Timer(interval60Minutes);
checkForTime.Elapsed += new ElapsedEventHandler(checkForTime_Elapsed);
checkForTime.Enabled = true;
Console.WriteLine("Waiting..");
Console.ReadLine();
}
public static void checkForTime_Elapsed(object sender, ElapsedEventArgs e)
{
GetApplicationPoolNames();
}
public static string GetApplicationPoolNames()
{
ServerManager manager = new ServerManager();
string status;
//string DefaultSiteName = System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
//Site defaultSite = manager.Sites[DefaultSiteName];
string appVirtaulPath = HttpRuntime.AppDomainAppVirtualPath;
string mname = System.Environment.MachineName;
string appPoolName = string.Empty;
manager = ServerManager.OpenRemote(mname);
ObjectState result = ObjectState.Unknown;
ApplicationPoolCollection applicationPoolCollection = manager.ApplicationPools;
foreach (ApplicationPool applicationPool in applicationPoolCollection)
{
//result = manager.ApplicationPools[appPoolName].State;
result = applicationPool.State; *// here exception occures*
Console.WriteLine("State : " + result);
Console.ReadLine();
}
}
What is wrong in the code? If there are any other ways to achieve this please provide as that will also help me to understand the main cause of exception message.
Any help is appreciated.
Thanks.
The asked question was too old but thought to share the solution which might help someone to resolve this kind of error/exception occurs when trying to get/read the IIS App Pool info of the server.
To resolve the Unauthorized Access Exception while trying to access the IIS info, First provide server credentials using DirectoryEntry Class like below -
DirectoryEntries appPools = new DirectoryEntry("IIS://" + ServerName + "/W3SVC/AppPools", UName, Pwd).Children;
This will give the access of IIS of the respective server.
So, The complete GetApplicationPoolNames() method after modification is -
public static string GetApplicationPoolNames()
{
// Get Server Credentials and Server Name from config file
string UName = ConfigurationManager.AppSettings["User"];
string Pwd = ConfigurationManager.AppSettings["Pass"];
string ServerName = DT.Rows[i]["ServerName"].ToString().Trim(); //Server Names from db
DirectoryEntries appPools = null;
try
{
appPools = new DirectoryEntry("IIS://" + ServerName + "/W3SVC/AppPools", UName, Pwd).Children;
}
catch(Exception ex)
{
log.ErrorFormat("serviceLogic -> InsertStatus() -> IIS Pool App Region -> DirectoryEntries -> Error: ", ex.Message.ToString());
}
log.Info("IIS App Pool Section Started for " + System.Environment.MachineName.ToString());
try
{
foreach (DirectoryEntry appPool in appPools)
{
log.Info("App Pool : " + appPool.Name.ToString());
int intStatus = 0;
string status = "";
try
{
if (appPool.Name.ToString().ToLower().Trim() == DT.Rows[i]["AppPoolSrvName"].ToString().ToLower().Trim())
{
log.Info("Process Started for App Pool : " + appPool.Name.ToString());
intStatus = (int)appPool.InvokeGet("AppPoolState");
switch (intStatus)
{
case 2:
status = "Running";
break;
case 4:
status = "Stopped";
break;
default:
status = "Unknown";
break;
}
//Store status info to db or file Logic goes here..
//Start App pool, If any application pool status is not Running.
if (status != "Running")
appPool.Invoke("Start", null);
log.Info("Process Completed for App Pool : " + appPool.Name.ToString());
}
}
catch (Exception ex)
{
log.ErrorFormat("serviceLogic -> InsertStatus() -> IIS Pool App Region -> Error: ", ex.Message);
}
}
}
catch (Exception ex)
{
log.ErrorFormat("serviceLogic -> InsertStatus() -> IIS Pool App Region -> DirectoryEntries -> Error: ", ex.Message);
}
}

CoreScanner errors on client

I have a C# application that uses the CoreScanner.dll and SNAPI API. Everything works fine on my development computer but once I install the application on a client PC it gives a few errors.
Retrieving the COM class factory for component with CLSID {} failed due to the following error: 80080005 or Creating an instance of the COM component with CLSID {} from the IClassFactory failed due to the following error: 80010108.
And if I dont get either of those errors, I can back Object reference not set to an instance of an object when I call one of the scanner methods.
try
{
try
{
cCoreScanner = (CCoreScannerClass)Activator.CreateInstance(typeof(CCoreScannerClass));
}
catch (Exception e)
{
using (LogManager lm = new LogManager())
{
lm.WriteErrorTextLog(e, "Setup Scanner - Splash Screen - Scanner Created");
}
}
short[] scannertTypes = new short[1];
scannertTypes[0] = 1;
short numberOfScannerTypes = 1;
int[] connectedScannerList = new int[255];
try
{
cCoreScanner.Open(0, scannertTypes, numberOfScannerTypes, out status);
}
catch (Exception e)
{
using (LogManager lm = new LogManager())
{
lm.WriteErrorTextLog(e, "Setup Scanner - Splash Screen - Scanner Open " + status.ToString());
}
}
try
{
cCoreScanner.GetScanners(out numberOfScannerTypes, connectedScannerList, out outXML, out status);
}
catch (Exception e)
{
using (LogManager lm = new LogManager())
{
lm.WriteErrorTextLog(e, "Setup Scanner - Splash Screen - Get Scanners " + status.ToString());
}
}
try
{
xmlDoc = new XmlDocument();
}
catch (Exception e)
{
using (LogManager lm = new LogManager())
{
lm.WriteErrorTextLog(e, "Setup Scanner - Splash Screen - XML Create");
}
}
try
{
xmlDoc.LoadXml(outXML);
}
catch (Exception e)
{
using (LogManager lm = new LogManager())
{
lm.WriteErrorTextLog(e, "Setup Scanner - Splash Screen - XML Load");
}
}
try
{
scannerID = xmlDoc.DocumentElement.GetElementsByTagName("scannerID").Item(0).InnerText;
}
catch (Exception e)
{
using (LogManager lm = new LogManager())
{
lm.WriteErrorTextLog(e, "Setup Scanner - Splash Screen - Get ScannerID");
}
}
try
{
cCoreScanner.BarcodeEvent += new _ICoreScannerEvents_BarcodeEventEventHandler(onBarcodeScan);
inXML = "<inArgs>" +
"<scannerID>" + scannerID + "</scannerID>" +
"</inArgs>";
cCoreScanner.ExecCommand(2014, inXML, out outXML, out status);
opCode = 1001;
inXML = "<inArgs>" +
"<cmdArgs>" +
"<arg-int>1</arg-int>" + // Number of events you want to subscribe
"<arg-int>1</arg-int>" + // Comma separated event IDs
"</cmdArgs>" +
"</inArgs>";
cCoreScanner.ExecCommand(opCode, ref inXML, out outXML, out status);
}
catch (Exception e)
{
using (LogManager lm = new LogManager())
{
lm.WriteErrorTextLog(e, "Setup Scanner - Splash Screen - Enable Scanner, Subscribe to barcode event");
}
}
}
catch (Exception ex)
{
using (LogManager lm = new LogManager())
{
lm.WriteErrorTextLog(ex, "Setup Scanner - Splash Screen");
}
}
I'm not sure where I am going wrong. I have the DLL registered, the SNAPI driver is installed on the client, and I've used the 123Scan utility to set the scanner up for SNAPI input. The client is a Win 7 64 bit, but I've also been testing on a Win XP and getting the same results. Developing on Win 7 32 bit, only difference is my computer as the SDK on it while the others don't.
Update: I finally found the CoreScanner driver on the Motorola website, however the 80010108 error will still happen, but if you restart the application, everything loads fine. Not 100% sure why its failing still but at least it works until the application closes.
Update 2: It seems only to fail after the application is re-installed. After that it will close / open just fine with no errors. Still have no clue has to why it doesn't work the 1st time but at least it works after that.

Categories