Error while using SHDocVw.InternetExplorer in C#2.0 - c#

all,
I have code in C# 2.0 like this:
SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindowsClass();
foreach (SHDocVw.InternetExplorer ie in shellWindows)
{
//.........
}
It is console exe for a 64bit Windows Server 2008 R2 Standard with sp1, IE9.
Basically it launches IE and download a file, then process that file.
When I run it manually, such as double click or from Command console, it works just fine. However, when I set up a Scheduled Task through Task Scheduler, it throws the error at the first line above:
Retrieving the COM class factory for component with CLSID {9BA05972-F6A8-11CF-A442-00A0C90A8F39} failed due to the following error: 8000401a.
I think it must be a permission issue,but I couldn't figure out how to fix it. Any ideas?
Thanks.

I suspect this is to do with access to the desktop.
As shdocvw has a UI, it requires permission to get the desktop handle. When it creates a window it must have a parent window and the desktop window handle is king (or Queen).
However, a scheduled task (for any user) cannot get the desktop handle unless the user is already logged-in in the foreground.

Related

Console application starting another process environment variables not accessible

I have a VB6 executable which is accessing some system environment variables. I have implemented a .NET console application which checks if those environment variables exist, creates them if needed, and then runs the VB6 application by calling Process.Start.
Doing this, the VB6 application cannot find the environment variables and it says they don't exist.
If I run the VB6 application from Windows Explorer it works fine and can find the variables.
So it seems the VB6 app is running under the context of .NET console app and cannot access the system environment variables!
Code to set the environment vars .NET Cosnole app:
foreach(var varObject in Variables)
{
var envVar = Envrionment.GetEnvironmentVariable(varObject.Name ,
EnvironmentVariableTarget.Machine);
if(string.IsNullOrEmpty(envVar)
{
Environment.SetEnvironmentVariable(varObject.Name,varObject.Value,
EnvironmentVariableTarget.Machine);
}
}
Code to run the VB6 app from .NET Cosnole app:
var processInfo = new ProcessStartInfo(VB6ApplicationFilePath);
processInfo.UseShellExecute = true
processInfo.WindwoStyle= ProcessWindowStyle.Hidden;
Process.Start(processInfo);
A copy of a program's environment is passed to a program that it starts. As it is a copy the second program only sees the state it was in when given it (and changes it made). No other program can change another program's environment.
When using ShellExecute (which you tell ProcessStart to) you are asking Explorer to start the program for you. The program will get a copy of Explorer's environment.
When changing the system environment, programs can send a message to all windows open saying environment has changed (as setx does - see setx /?). But ONLY Explorer.exe pays attention to this message. So only programs started by explorer after explorer receives this message will see the changes.
These are the API calls that .NET calls. In Windows all programs are started by CreateProcessEx (or older programs CreateProcess). Shellexecute and ShellexecuteEx process the command like you typed it in Explorer's Start - Run dialog (Winkey + R) then changes it and calls CreateProcessEx.
At the command prompt. Type
set MyCat=PewResearch
cmd /k echo %MyCat%
We set an environment variable, start a new command prompt that prints that variable.
This is the message that notifies
WM_SETTINGCHANGE
The system sends the WM_SETTINGCHANGE message to all
top-level windows when the SystemParametersInfo function changes a
system-wide setting or when policy settings have changed.
Applications should send WM_SETTINGCHANGE to all top-level windows
when they make changes to system parameters. (This message cannot be
sent directly to a window.) To send the WM_SETTINGCHANGE message to
all top-level windows, use the SendMessageTimeout function with the
hwnd parameter set to HWND_BROADCAST.

C# Get running Outlook instance in VSTO add-in

I am trying to get an Outlook Application object in my add-in for Excel.
If there's a running Outlook instance, it should get that, if there isn't any, it should create one, using the Outlook object model.
This is the code I have right now:
public static Outlook.Application GetApplicationObject()
{
Outlook.Application application = null;
if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
{
application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else
{
application = new Outlook.Application();
}
return application;
}
My problem: it finds Outlook processes, but can't get them, throwing the following error message:
Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))
I tried debugging it step by step, and monitored the task manager. I could see that I have an Outlook instance, but it's only an icon in the right side of the taskbar. Does this mean, that the instance is not fully loaded yet, and it can't be accessed, to get the Application object from it?
I ended up modifying my code, and separating the if-else into 2 try-catches, with their own returns, but I still think that the code above should be usable.
Outlook is a singleton, so new Outlook.Application() will always work - if it is already running, you will get that running object.
Make sure both apps (Excel and Outlook) are running in the same security context. Is either app running with elevated privileges (Run As Administrator)?

C# DCOM event binding Unathorized Execption

For a project I am working on I have to interface with a third-party DCOM library. I started with COM interop and this worked just fine locally, then I switched to DCOM and now I keep getting an unauthorized access exception (0x80070005) when trying to bind an event handler to the exposed event. Below is a summary of what I do in code:
public void connect(string server)
{
object dcomObj = null;
var guidB = Guid.Parse("c8c1f57f-0d7c-40b3-b17c-2eac12512006");
var typ = Type.GetTypeFromCLSID(guidB, server, true);
object[] url = { new UrlAttribute(server) };
dcomObj = Activator.CreateInstance(typ, null, url);
user = (RemoteObjectInterface)dcomObj ;
user.getState(); //works fine locally and remotely
user.stateChange += this.User_StateChange; //only works locally
}
I tried setting every permission I could find on the web but I without success. Does anyone have an Idea as to why only the binding of events fails?
RemoteObjectInterface inherits from both the IRemoteObjectEvents and the IRemoteObject. These interface come from the interop ms generated for me when I imported the original dll.
The server is a windows server 2003 VM in virtual box with a bridged network adapter. On the server Everyone is admin (including guest) and limits are set to full access and defaults are set to full access. I am building and running my code on c# .net 4.5.2 from a Windows 10 machine using visual studio 2015.
The sample application that comes with the SDK also fails when I try to use it remotely, the server registers the user but the sample application never realizes that it logged in successfully, I suspect that this behaviour is related to the failing of event binding.
TL;DR I can get and use a remote object but when I try to add an event handler I get an unauthorized exception (0x80070005), why does this happen on event binding? And how do I fix it?
I had the same problem.
For me the issue was I had a AD running on the same device and had to disable the loopback check in the registry. Other solution could be better I assume, but for me the registry hack will do.

My C# application is returning 0xE0434352 to Windows Task Scheduler but it is not crashing

I have written a few C# apps that I have running via windows task scheduler. They are running successfully (as I can see from the log files that they are writing ) but windows task scheduler shows them returning a last run result of 0xE0434352. Is there something I need to do in my C# application so that it returns a success code to the windows task scheduler?
Another option is to simply use the Application log accessible via the Windows Event Viewer. The .Net error will be recorded to the Application log.
You can see these events here:
Event Viewer (Local) > Windows Logs > Application
When setup a job in new windows you have two fields "program/script" and "Start in(Optional)". Put program name in first and program location in second.
If you will not do that and your program start not in directory with exe, it will not find files that are located in it.
Hans Passant was correct, I added a handler for AppDomain.CurrentDomain.UnhandledException as described here http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception(v=vs.71).aspx I was able to find the exception that was occurring and corrected it.
I was referencing a mapped drive and I found that the mapped drives are not always available to the user account that is running the scheduled task so I used \\IPADDRESS instead of MAPDRIVELETTER: and I am up and running.
In case it helps others, I got this error when the service the task was running at didn't have write permission to the executable location. It was attempting to write a log file there.
I had this issue and it was due to the .Net framework version. I had upgraded the build to framework 4.0 but this seemed to affect some comms dlls the application was using. I rolled back to framework 3.5 and it worked fine.
I got the same error but I have fixed it by changing the file reading path from "ConfigFile.xml" to AppDomain.CurrentDomain.BaseDirectory.ToString() + "ConfigFile.xml"
In my case, this error due to file path error because task manager starts program from "System32" as initial path but the folder we thought.
I was getting the same message message within dotNet Core 2.2 using MVC 5, however nothing was being logged to the Windows Event Viewer.
I found that I had changed the Project sdk from Microsoft.NET.Sdk.Web to Microsoft.NET.Sdk.Razor (seen within the projects.csproj file). I changed this back and it worked fine :)
In my case it was because I had message boxes. Once I commented that code out, it started working. I remembered that could be a problem when I looked at the event log as suggested in this thread. Thank you everyone!
I encountered this problem when working with COM objects. Under certain circumstances (my fault), I destroyed an external .EXE process, in a parallel thread, a variable tried to access the com interface app.method and a COM-level crash occurred. Task Scheduler noticed this and shut down the app. But if you run the app in the console and don't handle the exception, the app will continue to work ...
Please note that if you use unmanaged code or external objects (AD, Socket, COM ...), you need to monitor them!
Also message box in PowerShell. I converted PowerShell script to exe. When running as admin it's worked but in task schedule I received this error also.
There was an line in PowerShell script with write-output. After commented this line and compile new exe Task Schedule was completed successfully.
It is permission issue in my case the task scheduler has a user which doesn't have permission on the server in which the database is present.

System.Diagnostics.Process.Start() cannot start process when called from Windows service

I am trying to start an external process from a .NET Windows service. In the past I have used the Process.Start() overload that takes the executable path and a command line string. This works. But now I would like to start the process and have it run in the context of a particular user. So I call this version of Start()
public static Process Start(
string fileName,
string userName,
SecureString password,
string domain)
However, when I call the method, the application I am trying to run generates an unhandled exception:
The application failed to initialize properly (0xc0000142). Click on OK to terminate the application.
I have tried to start different applications and they all generate the same exception. I have run the code outside of the Windows service and the application starts correctly.
So is there a way to get this to work in a Windows service?
Maybe the user has to have, "logon as a service" security right. This is done with the "local security policy" application. And/or "logon as a batch job".
This is very similar to this question here. The answer is usually due to security issues with the desktop and window station in which the process is being run. See this article for an explanation and some sample code.
This is just a shot in the dark, but perhaps you can try to run the Windows Service in Interactive mode. If that works, though, this can't be done in Windows Vista (because of Session 0 Isolation).
Use Filemon and see if it is trying to open a config file and not finding it. I once had this error due to a malformed config.

Categories