Does anyone know why Redemption won't successfully logon?
What I'm doing is removing the default folders from a newly created PST. This is not an issue with any machines internally but on a clients machine, they get the following error.
Exception Source: Redemption.RDOSession
Exception Type: System.Runtime.InteropServices.COMException
Exception Message: Not logged on. Please log on first
Exception Target Site: Logoff
public static void DeleteStoreFolders(string sStorePath)
{
RDOSession session = null;
RDOPstStore RDOstore = null;
try
{
_logger.LogDebug("init RDOSession");
session = RedemptionLoader.new_RDOSession();
_logger.LogDebug("RDOSession created");
_logger.LogDebug("Logging into store: " + sStorePath);
RDOstore = session.LogonPstStore(sStorePath);
_logger.LogDebug("Logged into store: " + sStorePath);
foreach (RDOFolder folder in RDOstore.IPMRootFolder.Folders)
{
_logger.LogDebug("Deleting folder " + folder);
folder.Delete();
_logger.LogDebug("Folder " + folder + " deleted");
if (folder != null)
Marshal.FinalReleaseComObject(folder);
}
}
catch (Exception ex)
{
_logger.LogError("Unable to delete default folders. " + ex.StackTrace);
}
finally
{
if (session != null)
{
session.Logoff();
Marshal.FinalReleaseComObject(session);
}
if (RDOstore != null)
Marshal.FinalReleaseComObject(RDOstore);
}
}
It would be great to see the log generated on the problematic machine in addition to the exception details.
Also, I'd suggest replacing the FinalReleaseComObject methods with ReleaseComObject ones. The Marshal.FinalReleaseComObject method releases all references to a Runtime Callable Wrapper (RCW) by setting its reference count to 0. That is not really a good idea. The Marshal.ReleaseComObject method decrements the reference count of the Runtime Callable Wrapper (RCW) associated with the specified COM object. So, if you increase the reference counter, you need to decrease it accordingly, but not set it to zero!
Related
I wrote a code in c# in Visual studio and I open excels, run macro and close the excel
I do it in cycles (in a loop and delay between every cycle)
sometimes the function failes and sometimes it works
The error message I got:
"The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT))"
Please can someone help me ???
public void Open()
{
try
{
ExcelApp.Workbooks.Open(#"C:\Program Files (x86)\REFPROP\REFPROP.XLA");
ExcelApp.Workbooks.Open(#"C:\Program Files (x86)\REFPROP\REFPROP_Ribbon.xlam");
foreach (Excel.AddIn item in ExcelApp.AddIns)
{
if (item.Name.Equals("REFPROP.XLA") || item.Name.Equals("REFPROP_Ribbon.xlam"))
{
item.Installed = false;
item.Installed = true;
}
}
Thread.Sleep(3000);
//so then opening excel workbooks:
ExcelBook = ExcelApp.Workbooks.Open(ExcelPath);
Opened = true;
Thread.Sleep(3000);
ExcelApp.Workbooks.Open(#"C:\Program Files (x86)\REFPROP\REFPROP.XLA");
ExcelApp.Workbooks.Open(#"C:\Program Files (x86)\REFPROP\REFPROP_Ribbon.xlam");
foreach (Excel.AddIn item in ExcelApp.AddIns)
{
if (item.Name.Equals("REFPROP.XLA") || item.Name.Equals("REFPROP_Ribbon.xlam"))
{
item.Installed = false;
item.Installed = true;
}
}
Thread.Sleep(3000);
}
catch (Exception e)
{
throw;
}
}
There can be multiple reasons why you are getting that exception at runtime.
First, I'd suggest releasing underlying COM objects in the code and do not rely on the GC. Use the Marshal.ReleaseComObject method for that and then set the object to null.
Second, try to set the calculation mode to manual.
Third, make sure that the file doesn't require admin privileges.
You may find a similar thread helpful, see Excel interop The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT)).
I have a Windows Service that I successfully deploys, successfully works when debugging, but crashes when a file is added to the monitored directory.
I thought it was an issue with my impersonator being used between the OnStart and InputOnChanged, but the crash still happens when I run the service under my own domain user.
I have EventLog set to write to it's own application source, but none of my WriteEntrys are called except the one in the OnStart function. I've been trying different tweaks and feel like I need another set of eyes to see something i'm not:
protected override void OnStart(string[] args)
{
//using(Impersonator context = new Impersonator("XXXXX", "XXXXXXXX", "XXXXXXXXXX"))
//{
try
{
this.fileWatcherService = new FileSystemWatcher(baseFilePath, "*.txt")
{
NotifyFilter = NotifyFilters.LastWrite
};
fileWatcherService.Changed += InputOnChanged;
fileWatcherService.EnableRaisingEvents = true;
eventLog.WriteEntry("XXXX-XXXXX-Service Started");
}
catch (Exception ex)
{
eventLog.WriteEntry($"{baseFilePath} was not accessible to monitor because {ex.Message}", EventLogEntryType.Error);
}
}
protected void InputOnChanged(object source, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Changed)
{
eventLog.WriteEntry($"Change Detected - File {e.Name}", EventLogEntryType.Information);
try
{
fileWatcherService.EnableRaisingEvents = false;
eventLog.WriteEntry("Starting process for file: " + e.Name);
if (!File.Exists(e.FullPath))
{
eventLog.WriteEntry($"{e.Name} was not accessible", EventLogEntryType.Error);
}
//Copy File to backup copy before formatting
File.Copy(e.FullPath
, Path.Combine(#"\\XXXXXX\XXXXXX\XXXXXXXX\XXXXXXXXXX XXX XXXXXXXXX\XXX\XXXX\XXXX\BackupFiles", GetBackupFileName(e.Name))
, false);
//Save formatted file to directory
List<string> lines = System.IO.File.ReadAllLines(e.FullPath).ToList();
File.WriteAllText(Path.Combine(#"\\XXXXXX\XXXXXX\XXXXXXXX\XXXXXXXXXX XXX XXXXXXXXX\XXX\XXXX\XXXX\FormattedFiles", GetFormattedFileName(e.Name))
, CSVFormatService.FormatLines(lines));
//Remove file from base path to prevent re-processing
File.Delete(e.FullPath);
eventLog.WriteEntry($"Successfully moved {e.FullPath}", EventLogEntryType.Information);
}
catch (Exception ex)
{
eventLog.WriteEntry("XXXX-XXXXX-Service exception: " + ex.Message, EventLogEntryType.Error);
}
finally
{
fileWatcherService.EnableRaisingEvents = true;
}
}
}
Would expect eventLog.WriteEntry("Starting process for file: " + e.Name); to update the Application log at least because that is before any attempt to touch a file, but I don't see that in the log. However, the service runs until I place a test file in the monitored directory, and then crashes with a unhandled exception of file does not exist
When building out these services, make sure you reference a shared project correctly. This issue was caused by adding a reference to a class library to the project, but the .dll was missing when deploying the service. So when the service tried to access the .dll to process data a FileNotFound exception was being thrown. This also make sense as to why the exception was marked as unhandled.
I am trying to programmatically get my site status from IIS to see if it's stopped, but I kept getting the following error,
The object identifier does not represent a valid object. (Exception from HRESULT: 0x800710D8)
The application is using ServerManager Site class to access the site status. Here is the code,
//This is fine, gets back the site
var serverManager = new Microsoft.Web.Administration.ServerManager(ConfigPath);
var site = serverManager.Sites.FirstOrDefault(x => x.Id == 5);
if (site == null) return;
var appPoolName = site.Applications["/"].ApplicationPoolName;
//error!
var state = site.State;
I've test with static site to isolate the issue, making sure that the site is up and running, all configuration are valid, point to the valid application pool...etc.
Let me know if you need more details. Is it the COM thing?
I figured out where the problem is. Basically, there are two parts to the Server manager, the first part of the server manager allows you to read site details from configuration file, which is what I've been doing above. The problem with that is you will only able get the information that's in file and site state is not part of it.
The second part of the Server Manager allows you to connect to the IIS directly and it does this by interacting with the COM element. So what I should be doing is this:
ServerManager manager= ServerManager.OpenRemote("testserver");
var site = manager.Sites.First();
var status = site.State.ToString() ;
I had a similar problem but mine was caused by the delay needed to activate the changes from the call to CommitChanges on the ServerManager object. I found the answer I needed here:
ServerManager CommitChanges makes changes with a slight delay
It seems like polling is required to get consistent results. Something similar to this solved my problem (I got the exception when accessing a newly added application pool):
...
create new application pool
...
sman.CommitChanges();
int i = 0;
const int max = 10;
do
{
i++;
try
{
if (ObjectState.Stopped == pool.State)
{
write_log("Pool was stopped, starting: " + pool.Name);
pool.Start();
}
sman.CommitChanges();
break;
}
catch (System.Runtime.InteropServices.COMException e)
{
if (i < max)
{
write_log("Waiting for IIS to activate new config...");
Thread.Sleep(1000);
}
else
{
throw new Exception(
"CommitChanges timed out efter " + max + " attempts.",
e);
}
}
} while (true);
...
I have been put in charge of updating a service that reads a text file and creates pdf files from sections of the text file and emails out the pdfs. I recently made some changes to the service and used the .Net 4.0 Framework. When updating on the server, the 4.0 Framework was installed before I could move my files and start the service successfully - it was using 2.0 previously. The service runs until it reaches code that attempts to clean up the directory with the pdf files. The service Stops when the code attempts to delete a pdf file which is "in use by another process". The code looks for this exception and is supposed to wait for about 30 seconds and try the delete again. Locally, I run this service through a test Harness and it loops through until the file becomes available to delete (on average it takes about 5 minutes), but on the server the Service stops with the Unhandled IOException found in the Application Event log. I don't understand why it will continue processing locally but not on the server. Any ideas or other information would greatly be appreciated.
Here is the error in the Event Log:
The process was terminated due to an unhandled exception.
Exception Info: System.IO.IOException
Stack:
at System.IO.__Error.WinIOError(Int32, System.String)
at System.Console.GetBufferInfo(Boolean, Boolean ByRef)
at processorName.FileProcessingThread.CleanUpDirectory(System.Object)
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart(System.Object)
Also this error appears in the event log as well:
EventType clr20r3, P1 myServiceName.exe, P2 1.0.1.0, P3 4db6e85d, P4 mscorlib, P5 4.0.0.0, P6 4d53693b, P7 3dab, P8 23b, P9 system.io.ioexception, P10 NIL.
Here is the code that is supposed to handle the exception, wait and retry to delete the files.
while (!isDone)
{
bool myRetVal = true;
string myErrorMsg = String.Empty;
string myFile = String.Empty;
//give it time to finish processing
Thread.Sleep(30 * 1000);
//
//delete Files in folder
foreach (string file in Directory.GetFiles(myDirectory, "*.PDF"))
{ //delete all the *.PDF files
try
{
File.Delete(file);
}
catch (Exception ex)
{
myErrorMsg = "...\r\n" + ex.Message;
m_Log.Writeline("Unable to delete "+ file + ". MESSAGE:"+ myErrorMsg,3);
myFile = file;
myRetVal = false;
}
}
//
//now move the in-progress File to the processed directory
if (myRetVal)
{
foreach (string file in Directory.GetFiles(myDirectory, "*.InProgress"))
{
try
{
if (File.Exists(m_ConfigFile.ProcessedFolderName + Path.GetFileNameWithoutExtension(file) + ".done"))
{
File.Delete(file);
}
else
{
File.Move(file, m_ConfigFile.ProcessedFolderName + Path.GetFileNameWithoutExtension(file) + ".done");
}
}
catch (Exception ex)
{
if (ex.Message.Contains("file already exists"))
{
}
else
{
myErrorMsg = "...\r\n" + ex.Message;
myFile = file;
myRetVal = false;
}
}
}
}
//
//if empty, delete the SendMailFolder subfolder
if (myRetVal)
{
try
{
if (Directory.GetFiles(myDirectory, "*.*").Length == 0) Directory.Delete(myDirectory);
}
catch (Exception ex)
{
myErrorMsg = "...\r\n" + ex.Message;
myFile = myDirectory;
myRetVal = false;
}
}
if (Console.CursorLeft > 0) Console.WriteLine("\r\n");
if (myRetVal)
{
Console.WriteLine(DateTime.Now.ToLocalTime() + " CleanUp SendMailFolder...Done");
isDone = true;
}
else
{
if (myErrorMsg.Contains("is being used by another process."))
{
myErrorMsg = " is still in use.";
Console.WriteLine(DateTime.Now.ToLocalTime() + " CleanUp SendMailFolder..." + Path.GetFileName(myFile) + myErrorMsg);
}
else
{
Console.WriteLine(DateTime.Now.ToLocalTime() + " CleanUp SendMailFolder..." + Path.GetFileName(myFile) + myErrorMsg);
m_Log.Writeline(DateTime.Now.ToLocalTime() + " CleanUp SendMailFolder..." + Path.GetFileName(myFile) + myErrorMsg, 3);
isDone = true;
}
}
}
You're trying to use the Console class in a service, which doesn't have a console window associated with it. You should use some alternate form of logging that doesn't assume there's a console window. log4net, as one example, allows you to configure multiple "appenders", such as a console, file, and event log appender, to use simultaneously (and which will simply be ignored if they aren't appropriate).
EDIT to clarify:
You can create a console window manually with the AllocConsole P/Invoke call if you absolutely need to. By default, a service doesn't interact with your desktop, so creating a console window would be a bad idea. For that to work you would need to configure the service with the "Allow service to interact with the desktop" setting turned on. This has security implications, particularly for machines that have multiple users, so I would advise against it.
It looks like there error is happening before your try catch. Given that you should see the specific message output by your logging (I assume it goes to the Event Log). I don't see a message that looks like what is in your log. You might want to have an app domain exception handler to catch any exceptions and log them.
Also you should ensure your m_log routine has proper error handling as that could be the culprit as well.
Have a windows service that listens to a msmq. In the OnStart method is have this
protected override void OnStart(string[] args)
{
try
{
_queue = new MessageQueue(_qPath);//this part works as i had logging before and afer this call
//Add MSMQ Event
_queue.ReceiveCompleted += new ReceiveCompletedEventHandler(queue_ReceiveCompleted);//this part works as i had logging before and afer this call
_queue.BeginReceive();//This is where it is failing - get a null reference exception
}
catch(Exception ex)
{
EventLogger.LogEvent(EventSource, EventLogType, "OnStart" + _lineFeed +
ex.InnerException.ToString() + _lineFeed + ex.Message.ToString());
}
}
where
private MessageQueue _queue = null;
This works on my machine but when deployed to a windows 2003 server and running as Network service account, it fails
Exception recvd:
Service cannot be started. System.NullReferenceException: Object reference not set to an instance of an object.
at MYService.Service.OnStart(String[] args)
at System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(Object state)
Solved:
Turned out that the Q that i set up, I had to explicitly add Network Service account to it under security tab
You're seeing that particular exception because you're calling ex.InnerException.ToString(). The InnerException property is not always populated (in fact, it frequently isn't, nor should it be).
Your root problem is likely that the Network Service account doesn't have permissions to access the queue (in this case, read from it).
Here's some code that will help you get the actual error in your event log:
catch(Exception ex)
{
Exception e = ex;
StringBuilder message = new StringBuilder();
while(e != null)
{
if(message.Length > 0) message.AppendLine("\nInnerException:");
message.AppendLine(e.ToString());
e = e.InnerException;
}
EventLogger.LogEvent(EventSource, EventLogType, "OnStart" + _lineFeed +
message.ToString());
}