Error while starting a WPF-Application on System-Startup - c#

I have a WPF-Application that I would like to start automatically if I start my Computer.
I have a window where a user can configure some settings for the application, one of the possible configuration options is a checkbox, that allows the user to dis- or enable the application to automatically start on the System-Startup.
This is how I set or delete the value in the Registry, depending on the users choice in the Checkbox:
try
{
var currentAssembly = Assembly.GetExecutingAssembly();
var rkApp = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
if (settingsViewModel.AutostartEnabled)
{
rkApp.SetValue(currentAssembly.GetName().Name, currentAssembly.Location);
}
else
{
rkApp.DeleteValue(currentAssembly.GetName().Name, false);
}
}
catch (Exception exception)
{
}
My Problem is, that even though the Application gets registered and can also be seen in the Autostart-Section within the Task-Manager, that I get the following error every time I restart my computer to check if the Appliction is started:
"You are attempting to open a file of type Application extension (.dll)"
So what am I doing wrong? Is there any way to avoid this error or to fix it? I already tried adding an application manifest file to my project to always start my Application as an Administrator. But that didn't seem to work either.
I'd appreciate any help.

Try to use System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName instead of currentAssembly.Location.
This should give you the path of the running executable. Assembly.GetEntryAssembly does not.

Related

Directory exists is producing inconsistant results on desktop vs server

I have a C# program which checks if a specific directory exists.
It is simply doing:
Directory.Exists(path).
I tried other ways as well. Using DirectoryInfo and using AlphaFS
On my local machine, the path exists. When I run the same program on a server with the same credentials it doesn't exist.
I wonder if it is a group policy issue. But I am able to go up one level and see it.
\server\volume\share\sub directory - Doesn't exist remotely but on my desktop it does
\server\volume\share - Does exist both on my desktop and remote server
Update
I forgot to mention, that since I had access to my desktop, I got the ACL information.
None of the groups were able to translate.
I really just want to get this application to behave the same way is on the server and find out why it is behaving differently.
Update 2
These are physical servers.
My desktop is Liquid VDI
Below is the code:
var path = txtPath.Text;
using (var user = new Impersonation(fuserdomain, fc_user, fc_pass))
{
var alphaExists = Alphaleonis.Win32.Filesystem.Directory.Exists(path);
var alphaDIExists = new Alphaleonis.Win32.Filesystem.DirectoryInfo(path).Exists;
var SystemExists = System.IO.Directory.Exists(path);
var SystemDIExists = new System.IO.DirectoryInfo(path).Exists;
var AlphaHasFiles = false;
var AlphaDIHasFiles = false;
var SystemHasFiles = false;
var SystemDIHasFiles = false;
try
{
Directory.GetFiles(path);
AlphaHasFiles = true;
}
catch { }
try
{
new DirectoryInfo(path).GetFiles();
AlphaDIHasFiles = true;
}
catch { }
try
{
System.IO.Directory.GetFiles(path);
SystemHasFiles = true;
}
catch { }
try
{
new System.IO.DirectoryInfo(path).GetFiles();
SystemDIHasFiles = true;
}
catch { }
MessageBox.Show(string.Format("alphaExists: {0}\nalphaDIExists: {1}\nSystemExists: {2}\nSystemDIExists: {3}\nAlphaGetFiles: {4}\nAlphaDIGetFiles: {5}\nSystemGetFiles: {6}\nSystemDIGetFiles: {7}\n", alphaExists, alphaDIExists, SystemExists, SystemDIExists, AlphaHasFiles, AlphaDIHasFiles, SystemHasFiles, SystemDIHasFiles));
}
Update 3
Although I have workaround this issue; I am still not sure why I would have a difference between my desktop and server. Is there any tool that can help me see where the issue may be?
I've seen the same thing with File.Exists. I never found an answer and finally threw in the towel, I simply try to use it and catch the exception.
Robust code has to catch it anyway, all the test does is avoid trying if the file or directory is not there. (And the PITA that Visual Studio no longer as any way to ignore an exception on a certain line. No problem runtime, annoying in development.)
This is a complete shot in the dark, since we don't have any specific details to go on. e.g. Is the server you're talking about physically yours, or is it a cloud-based server service?
I'd guess that your machine is an older operating system than the server, and the folder that you're trying to access is one of those special folders that has become more locked down with more recent operating systems (particularly on server operating systems) like the "Program Files" folder. So even though the folder exists on both, the method works on your machine but not on the server, due to permissions.
Hope this helps.
As far as I can tell, the Impersonation class in your code is not part of the dot net framework. Googling finds a couple of implementations. Where does it come from and How confident are you that it actually works in your scenario?
For example, if you remove the Impersonation code, and actually run it as that user, does that make it work?
One other clarification... When you say
\server\volume\share
Do you mean this is a network location (e.g. a UNC location), so is the same network path you are trying to access from both machines? If so, this would open up new possibilities for problems like firewalls, etc... Is that location on either of the two machines that we know about from the question, or a different location?

Outlook.Interop - Checking if a folder is hidden

I have an odd problem. I have an application that allows a user to select folders from their Outlook mailboxes/stores, and it's supposed to skip over any folders that are hidden.
To accomplish this, I perform the following check on the folder:
try
{
if (folder.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x10F4000B"))
{
// Yes, it's a hidden folder
return true;
}
}
catch (System.Runtime.InteropServices.COMException comex)
{
// If the hidden property doesn't exist at all, we'll get a COM exception
// here, which is fine.
return false;
}
catch (Exception)
{
// Some other failure
throw;
}
Now, on my test machine, this works perfectly fine. I use MFCMAPI to toggle on/off the hidden attribute, and the application responds appropriately.
On another remote user's machine, ALL of their folders are showing up, even the normally-hidden ones like Quick Step Settings.
I turned up the logging and in the COMException catch() block, I end up seeing things like this:
Checking to see if Quick Step Settings is hidden: NOT HIDDEN
COMException: The property "http://schemas.microsoft.com/mapi/proptag/0x10F4000B" is unknown or cannot be found.
But I walked the user through examining that folder's properties via MFCMAPI and I took screenshots that show that the folder DOES have that hidden flag set to true. So I'm not sure why the application can't see that property...?
The user does make use of mailboxes that are online-only mailbox stores / shared mailboxes, so I'm wondering if there's maybe a different namespace for the property or something under certain circumstances? Can anyone weight in here?

C# Winform application couldn't run when Window startup

everyone
I have a problem with my application. I make an event that when I tick to a checkbox it will run when Window startup and I save this setting in a XML file. But it doesn't work and Window show me a message error "Stop working". Does anyone know what did I do wrong? I try to resolve it but it still. Thanks a lot. Here is my code:
private RegistryKey registrykeyApp = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Run", true);
private void checkBoxKhoidongcungwin_CheckedChanged(object sender, EventArgs e)
{
if (this.checkBoxKhoidongcungwin.Checked)
{
if(this.registrykeyApp.GetValue("ViKey") == null)
this.registrykeyApp.SetValue("ViKey", Application.ExecutablePath.ToString(),RegistryValueKind.ExpandString);
}
else
{
this.registrykeyApp.DeleteValue("ViKey", false);
}
}
That registry key cannot be accessed from an application that is not running with elevated privileges since viruses, etc could use it to hijack computers. Unfortunately when access is denied you often get generic errors that aren't obvious.
Right click on your exe and run it as administrator and it should work. If so you can add an application manifest to your project to always request the elevated privileges automatically, without manually right clicking.
http://www.samlogic.net/articles/manifest.htm

Process doesn't start with a correct user name

I am working on renewing an application. The old code had a main method which went through the running processes on windows and checked to see if a certain required process which is a part of the application is running, and if not it starts it. This is how it looks:
Process[] localProcesses = Process.GetProcesses(Environment.MachineName);
bool isHostAlive = false;
foreach (Process localProc in localProcesses)
{
if (localProc.ProcessName == "processIneed")
{
isHostAlive = true;
}
}
if (!isHostAlive)
{
try
{
Process.Start(Application.StartupPath + #"\bin\processIneed.exe");
}
....
Now what I did was adding an installer class in which I override the Commit method and there I'm activating the process so it will automatically run after installing the application. It looks like this:
string path = Context.Parameters["targetdir"].Replace(#"\\", #"\");
path += #"bin\processIneed.exe";
Process.Start(path);
The problem is that in the old way without activating the process during installation everything worked fine. When I'm starting the process in the new way I've implemented, I see that the path is being built correctly and the process do run in the backgroung but the application just doesn't work as it should.. It kinda "half" works.. I'm not getting any errors or exceptions but it just doesn't work.
The only difference I did notice is that with the old code the process was started under the user name which logged in to windows (user name and password entered in the login screen), while in the new code, the process starts under the user SYSTEM.
Is there a way to start the process from the installer class with the correct credentials? I want to clarify that I don't want to somehow request the password from the user and I don't want to save it or something.. just start with the currently logged on credentials and not with the SYSTEM user.

C# Application not run

C# VS 2005.
I have developed an application that run perfectly on my development machine when I install it. However, it doesn't run on any of the clients machines.
I have tested with VMWare with a fresh install of windows, and still the application doesn't run.
I have added logging to try and determine where the application is failing. My previous versions worked, and after a week of development I gave to the client and then experienced this problem.
I have entered logging at the start and end of the constructor and form_load event. The constructor runs ok. However, at the end of the constructor it doesn't run in the form_load event as I have a log statement that should print out.
When the application runs it displays for a few seconds in task manager then fails to load.
I think this could be a very difficult problem to solve. So if anyone has experienced this before or could point me in the right direction to solve this problem.
The code in the form load event.
private void CATDialer_Load(object sender, EventArgs e)
{
my_logger.Info("Start of form load event"); // Doesn't display this.
.
.
}
===== Edit static main ====
[STAThread]
static void Main()
{
Application.SetCompatibleTextRenderingDefault(false);
// Get the language and set this cultureUI in the statusdisplay that will
// change the language for the whole program.
string language = CATWinSIP.Properties.Settings.Default.Language;
if (language == "th-TH")
{
StatusDisplay.StatusDisplay status_display = new StatusDisplay.StatusDisplay(true);
}
else if(language == "en-GB")
{
StatusDisplay.StatusDisplay status_display = new StatusDisplay.StatusDisplay(false);
}
try
{
Application.Run(new CATDialer());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
=== Constructor ===
public CATDialer()
{
//Set the language for all the controls on the form.
//Has to be done before all components are initialized.
//If not Thai language then must be using English.
if (Settings.Default.Language == "th-TH")
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("th-TH");
}
else
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
}
InitializeComponent();
this.statusDisplay1.BalanceStatus = CATWinSIP_MsgStrings.BalanceStatus;
this.statusDisplay1.RedialHistory = CATWinSIP_MsgStrings.RedialHistory;
this.statusDisplay1.LoginStatus = CATWinSIP_MsgStrings.LoginSuccessful;
// Enable logging
XmlConfigurator.Configure();
logger.Info("CATDialer Constructor(): XmlConfigurator.Configure() Loaded [ OK ]");
// MessageBox.Show("Balance Status: " + this.statusDisplay1.BalanceStatus);
//Short cut menu.
this.SetupShortCutMenu();
this.fill_properties();
logger.Debug("CATDialer Constructor(): Fill properties loaded [ OK ]");
}
--
Hello,
Thanks for all the advice.
I have problem with one of my class libraries I created that used a crypto stream.
I found the answer when I added this to my program.cs
The message box displayed the information for the failed assembly.
Thanks,
try
{
Application.Run(new CATDialer());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Have you checked on a different development machine? Are your systems running same version of the .net framework? Is the .net framework installed correctly on the remote system? Have you tested your application in a different environment?
edit: have you tried spamming your log? Wrap the entire thing in a try catch and see what you can capture. Sometimes I found using the messagebox useful for this kind of logging (MessageBox.Show())
You probably need to post a bit more detail about the type of exception that is being thrown to get the most help.
If all the obvious checks such as having the correct framework version pass, the next thing to fail can often be a missing assembly.
If this is the case you may want to troubleshoot assembly loading in your app.
The MS Assembly Binding Log Viewer (fuslogvw) is a valuable piece of kit for this task.
In this sort of scenario I frequently find .NET assembly binding log viewer (Fusion) very useful in finding out what is going on. With fusion you can see which assemblies are being loaded and where they are being loaded from. More importantly for you, it is possible to enable it so that fusion also displays the assemblies that fail to load and where .NET tried to load them from.
Check out the MSDN article on fusion if you think this might help.

Categories