Can't add Schedule task in Win XP, limited user - c#

I've built a program in C# Windows Forms, now on the first load up it tries to create scheduled tasks. If it raises an exception and it's in main computer then this is the first time the softwere loads (you can intall this program on many computers but one computer is the main with the scheduled tasks).
I've tried this program on many computers and it worked perfectly (XP-SP1/2, Vista-SP1/2, Win7), now when I try to install it on a limited user (on Win XP Pro SP2) it tries to create the scheduled tasks. I get an Argument Null Reference and when I enter the admin user, it installs the scheduled task on the admin user and won't run if the limited user is logged in (which is 99.9% of the time) .Why do I get this exception? I've looked for hours on the code searching for the reason of this exception but I can't find it!
Thanks a lot!
Amit
MainOrSec = true;
User and Pass are public variables whice return from FirstTimeUp.
private bool CreateNoExit()
{
try
{
RegistryKey key = Registry.CurrentUser;
key = key.OpenSubKey("Crm");
MainOrSec = Convert.ToBoolean(AESIMP.Decrypt((string)key.GetValue(AESIMP.Encrypt("MorS"))));
}
catch (ArgumentNullException)
{
MainOrSec = true;
}
if (MainOrSec)
{
ScheduledTasks sc = new ScheduledTasks();
Task task;
try
{
task = sc.CreateTask("NoExit");
FirstTimeUp f = new FirstTimeUp(this);
f.ShowDialog();
}
catch (ArgumentException)
{
return false;
}
if (!CreatT)
return false;
task.ApplicationName = #"C:\Program Files\Triffon\Crm Setup
2.0.0002\noexit.exe";
task.Comment = "Check For no exit on the database.";
task.SetAccountInformation(User, Pass);
task.IdleWaitMinutes = 10;
task.Triggers.Add(new DailyTrigger(5, 0));
try
{
task.Save();
task.Close();
sc.Dispose();
}
catch (COMException ex)
{
MessageBox.Show(ex.Message);
return false;
}
return true;
}
return false;
}

OK, so if you get an exception, the best thing to do is to run your program under Visual Studio's debugger so you can see exactly where the exception is called. Here, Ctrl-Alt-E is your friend: turn on the checkbox in the "Thrown" column next to "Common Language Runtime Exceptions" and you'll break to the debugger no matter what.
If you are testing your application on a user's computer without Visual Studio then you have some other options. One (if you're using Pro and above) is to run the Remote Debugger on the remote PC. Then you can attach to the running program and see the exception.
If you don't have Pro, or can't easily use the remote debugger, then it is definitely worth using a decent logging framework like log4net to make sure that all exceptions are caught, trapped, and written to a log file. Frankly no production application should be released until this is done.
When you've done this, take a careful look at the exception trace to see where the problem is caused. I'd be willing to bet that that ScheduledTasks class is throwing an exception somewhere that you're not expecting.
Finally, you'll be getting downvotes because the culture here is "we'll help if you let us know everything we need to know to help." There's been a couple of requests in the comments for the full stack trace, which hasn't appeared, so people here will consider that rude, I'm afraid.

It's hard to figure this out without a stack trace, but there is a suspicious line of code.
According to MSDN RegistryKey.GetValue() returns:
The value associated with name, or a
null reference (Nothing in Visual
Basic) if name is not found.
Here you pass the result of that function directly to another function:
MainOrSec = Convert.ToBoolean(AESIMP.Decrypt((string)key.GetValue(AESIMP.Encrypt("MorS"))));
Try to call it in a few steps instead, checking for null where needed:
string s = key.GetValue(AESIMP.Encrypt("MorS")) as string;
if(!string.IsNullOrEmpty(s))
MainOrSec = Convert.ToBoolean(AESIMP.Decrypt(s));
else
MainOrSec = true;

Related

How to make [DebuggerNonUserCode] hide an exception from the debugger in simple test case?

Setup:
1) MSVS 2015, Option -> Debugger -> "Just My Code" is checked.
2) This sample code placed within some class and called during startup:
static bool TestIgnoreException()
{
Exception ex;
return TrySomething(out ex);
}
[DebuggerNonUserCode] // Prevent exceptions from stopping the debugger within this method.
static bool TrySomething(out Exception exOut)
{
try
{
if (Environment. MachineName.Length != -1)
throw new Exception("ThrewIt.");
exOut = null;
return true;
}
catch (Exception ex)
{
exOut = ex;
return false;
}
}
3) Launch Debugger
Expected result is that TestIgnoreException() runs silently and returns false.
Actual result is the debugger stops in TestIgnoreException() even though there should be no exception being processed at that scope.
4) Also re-tried using [DebuggerHidden] instead, same results.
Motivation:
The motivation is for cases where some API that is out of your control does not provide a "Try" method and instead only indicates failure by using exceptions.
One of numerous such examples is .NET TcpClient.Connect(host, port). Say a program always tests some connections during startup, the debugger should not stop on this particular section of code each time.
Using the standard "break when thrown" exceptions checkboxes is is not good because it works globally by type. It cannot be configured to work locally. Also other developers who check out the code should automatically skip the exception as well.
Mystery solved. It is indeed a known issue that is new to MSVS 2015 because of added exception handling optimizations.
https://blogs.msdn.microsoft.com/visualstudioalm/2016/02/12/using-the-debuggernonusercode-attribute-in-visual-studio-2015/#
There is a workaround posted on that link to disable the optimizations and enable the old behavior. Hopefully they will eventually be able to revive the support for this including the optimizations.
reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 1
Related question:
Don't stop debugger at THAT exception when it's thrown and caught

Environment.FailFast in c# application

I'd like to understand the Environment.FailFast rule in c# application. So , I made this code :
public static void Main()
{
string strInput = GetString();
Console.WriteLine(strInput);
Console.ReadKey();
}
private static string GetString()
{
Console.WriteLine("Get string");
string s = Console.ReadLine();
try
{
if (s == "Exit")
{
Environment.FailFast("Erreur fatale");
return s;
}
else
{
return s;
}
}
catch (Exception)
{
return "catch";
}
finally
{
s += "finally";
}
}
As I learned, the message are written to the Windows application event log and the application is terminated.
When I run the application and put Exit as a string :
The debbugger indicates an error :
I try to find the event log file, as indicated in msdn, but I don't find it
I don't understand why the application didn't shut down without throwing the exception? For the second point, How can I find the log file in my PC?
Environment.FailFast(string) exits the application immediately, without allowing any catch statements or finalizers to be run on the object.
You should only use this method if your application's state is at a point where it can never be recovered, and exiting the application is the only way to ensure something far worse than crashing does not happen. In your sample, using Environment.Exit with an exit code is more suitable, as it appears to be a graceful exit, rather than one forced through corrupt state.
In general, it is recommended to not use FailFast while the debugger is attached - this is documented in the System.Diagnostics.Assert class:
// However, in CLR v4, Environment.FailFast when a debugger is attached gives you an MDA
// saying you've hit a bug in the runtime or unsafe managed code, and this is most likely caused
// by heap corruption or a stack imbalance from COM Interop or P/Invoke. That extremely
// misleading error isn't right, and we can temporarily work around this by using Environment.Exit
// if a debugger is attached. The right fix is to plumb FailFast correctly through our native
// Watson code, adding in a TypeOfReportedError for fatal managed errors. We may want a contract-
// specific code path as well, using COR_E_CODECONTRACTFAILED.
Which means the exception you're seeing in Visual Studio is down to a bug in the CLR, and could be safely ignored.
Their work around is as follows:
if (Debugger.IsAttached)
Environment.Exit(COR_E_FAILFAST);
else
Environment.FailFast(message);
Which means that while running with the debugger attached, you won't get the Event Log message written, while in release you do.
I've reconstructed your problem with the following piece of code:
static void Main(string[] args)
{
try
{
Console.WriteLine("Foo");
Environment.FailFast("WOHO!");
}
finally { }
}
When running this under the debugger, I didn't see any exceptions registered either. Running this without the debugger (Ctrl + F5) makes the exception appear in the Event Viewer properly (see #aevitas answer or read this for why that happens):

Elmah throws ObjectDisposedException

I have an MVC app running on IIS 7 using windows authentication and Elmah logging.
Normally when an error happens, we call something like "logger.LogError" which is a wrapper for:
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception(message)));
We have a remote system set up to run jobs that pings the web application periodically, in order to wake it up and tell it to run a specific job. The remote application uses HttpClient::GetAsync(...) to connect to the site.
The page that the remote ping hits, executes the job it needs to run in a thread but does not await, since we want the ping to respond immediately. Unfortunately, this has the added drawback of breaking the Elmah logging.
If we have any kind of logged error occur during the job execution, when we get to the "LogError" method, Elmah throws an "ObjectDisposedException" with the message "Safe Handle has been closed" (probably bubbled up from trying to access the current users identity). I checked in the watch window while debugging, and the part that is throwing the error is:
new Elmah.Error(new Exception(message))
if I call just "new Elmah.Error()" it works fine, and "new Exception(message)" also works fine, but when passing an exception as the parameter to the error constructor, that's when it fails. Also, I cannot assign an exception after creating a new error object, as the property is read-only.
I'm pretty sure that it's because the current windows identity has gone out of scope in the parent thread when it finishes. Is there any way of getting around this issue without resorting to an await on the job execution? The problem is that the jobs can take a very long time to run, and we don't want the remote ping app to either timeout or hang for a long time while waiting for a response.
In case someone else runs across this, here's what I ended up doing:
In a situation where you'd normally call
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
Call this function instead:
public static void LogError(Exception ex)
{
if (HttpContext.Current == null)
{
var errorlog = Elmah.ErrorLog.GetDefault(null);
var error = new Elmah.Error();
error.Message = ex.Message;
error.Detail = ex.ToString();
error.Time = DateTime.Now;
error.Type = ex.GetType() + "[NoContext]";
error.HostName = Environment.MachineName;
errorlog.Log(error);
} else {
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
}
Caveats apply:
All this does is log to your default log. It won't send e-mail or do
any of the other fancy things Elmah can do with an HttpContext
You won't get the full yellow screen of death - just the ToString() representation of the exception, which is less useful.

C# .NET Error Attaching to Running Instance of Office Application

I am working on an Excel Addin using C#, Visual Studio 2012. I am trying to get the instance of Excel's Application object so as to keep track of the currently active workbook and worksheet (ActiveWorkbook, ActiveWorksheet).
I see that most other related questions on SO have replies suggesting to use the following:
(Excel.Application)Marshal.GetActiveObject("Excel.Application");
I have also tried using this:
(Excel.Application)Globals.ThisAddIn.Application;
In both of the cases I get NullReferenceException. After looking at the workaround suggested here: http://support.microsoft.com/kb/316125/en-us, I tried the following to test both methods.
public CurrentSpreadSheet()
{
try
{
this.CurrentApplication = (Excel.Application)Globals.ThisAddIn.Application;
}
catch (NullReferenceException)
{
MessageBox.Show("Excel application object not registered. Trying plan B..");
//Getting Excel's application object instance
int iSection = 0, iTries = 0;
tryAgain:
try
{
iSection = 1; //Attempting GetActiveObject
this.CurrentApplication = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
iSection = 0; //GetActiveObject succeeded so resume or go for normal error handling if needed
this.CurrentApplication.Visible = true;
}
catch (Exception err)
{
System.Console.WriteLine("Visual C# .NET Error Attaching to Running Instance of Office Application .. yet.");
if (iSection == 1)
{
//GetObject may have failed because the
//Shell function is asynchronous; enough time has not elapsed
//for GetObject to find the running Office application. Wait
//1/2 seconds and retry the GetObject. If we try 20 times
//and GetObject still fails, we assume some other reason
//for GetObject failing and exit the procedure.
iTries++;
if (iTries < 20)
{
System.Threading.Thread.Sleep(500); // Wait 1/2 seconds.
goto tryAgain; //resume code at the GetObject line
}
else
{
MessageBox.Show("GetObject still failing. Process ended.");
}
}
else
{
//iSection == 0 so normal error handling
MessageBox.Show(err.Message);
}
}
}
}
The output is:
Excel application object not registered. Trying plan B..
GetObject still failing. Process ended.
In some rare cases "plan B" does work; I don't see the second message box.
CurrentSpreadSheet is a singleton and I intend to update it during startup from the provided class ThisAddIn.
In ThisAddIn I have something like:
private CurrentSpreadSheet css = CurrentSpreadSheet.Instance;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
///...Some code
css.updateCurrentSpreadSheet();
}
Is there a better way of getting the Application object? If this is not possible right during the startup, is there a better way by which I can keep track of currently active worksheet/workbook right from the startup of excel/my add-in? Currently I am depending on the Application object (e.g. (Excel.Workbook)this.CurrentApplication.ActiveWorkbook;) and some event handlers to keep track of the current workbook and worksheet.
I tried using ExcelDNA:
this.CurrentApplication = (Excel.Application)ExcelDna.Integration.ExcelDnaUtil.Application;
This works some of the times but mostly gives this error:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> ExcelDna.Integration.XlCallException: Exception of type 'ExcelDna.Integration.XlCallException' was thrown.
Keep in mind that an Office add-in runs inside the Office process. So you never want to find an external process. The boilerplate ThisAddIn class that you get when you use a Office project template hands you the Application object you are looking for on a silver platter, use its Application property. The first time you can get to it is in the Startup event, make sure you don't try it earlier. So don't do anything drastic in your constructor and don't initialize class members with initialization expressions, wait until Startup fires.
The relevant MSDN page is here, "Accessing the Object Model of the Host Application" section.
You might take a closer look at http://netoffice.codeplex.com/ There you can find more stuff about Add-In's for Word/Excel/Powerpoint.
Also keep in mind the GuidAttribute when you load your Add-In, because depending on your Office version it won't work anymore and also, check to kept your project whether 32/64-bit, best is Any CPU. Also, keep in mind to register your Add-In into the registry for further usage. If you want further information, don't hesitate to write me a mail.
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.guidattribute.aspx

File.WriteAllText() runs OK, or does it?

I've been starting at this code for the best part of 2 hours (literally) but I can not seem to grasp why this would fail. This method below does not report any exceptions, yet it seems to return false:
public bool SaveFile(string filename, object source)
{
bool result = true;
StringBuilder exportText = new StringBuilder(source.ToString());
try {
File.WriteAllText(filename, exportText.ToString());
}
catch (Exception e)
{
OnPluginError(new ErrorEventArgs(e));
result = false;
}
return result;
}
The problem is: the file is properly written at the requested path, is complete, and readable. No exceptions are thrown, because the OnPluginError() handler invocation method isn't called - any message would be logged in that case, but there is nothing logged. It can't be a permission problem because the file does exist after the call.
And still, the method result is false.
The problem only appears in a Release build. In Debug builds, all seems to work OK. Hence, I can't use the debugger to step through.
This is called from a web application. Any ideas appreciated.
As a temporary troubleshooting step, add another try catch to block any exceptions and then see if the function is still returning false.
public bool SaveFile(string filename, object source)
{
bool result = true;
StringBuilder exportText = new StringBuilder(source.ToString());
try {
try {
File.WriteAllText(filename, exportText.ToString());
} catch(Exception e) { }
}
catch (Exception e)
{
OnPluginError(new ErrorEventArgs(e));
result = false;
}
return result;
}
If it is returning true, then you have isolated the problem and determined that an exception is being thrown, causing the block with result = false to be run.
If it is still returning false, then you can be certain the problem is outside of this function, as the rules of control flow would dictate that the result variable would never be changed.
One possibility is you have an issue with either the code you think is being run is not really being run. For example some issue with the build process not picking up your most recent code changes or redirection. Checking the versions of the website project DLLs, doing clean/rebuild, adding additoinal code to write out trace messages, are all things you should try to cross check to verify your most recent code is being run.
Another possibility is a problem in the code that is checking the return value.
Well...I do feel a bit silly here. I finally found the problem, and it is (as some posters questioned) not related to the WriteAllText() method at all.
FYI: this code ran deep inside an extensive plugin library. Not all that code was designed and written by me, and has been around for almost 2 years without running into problems.
As I mentioned, the WriteAllText() ran fine. It did. Problem was that the location of the file saved, was stored in a Dictionary, which in turn was requested from the plugin currently running. That Dictionary (containing plugin settings) turned out to be created from scratch with each call to that property! So I could add to it as much as I wanted....at the next call to that property, the newly added items would 'disappear' magically since the Dictionary was created anew.
Since it never surfaced before, and that code ran in a lot of other plugins with no problems, I didn't check that property. My bad.
Apologies to everyone that responded for wasting their time. Rest assured it won't happen any time soon! Lesson learned...

Categories