I have a C#/.NET (VS2010) IE add-on which uses Marshal.GetActiveObject() to a running instance of an application (COM object) and then send commands to it via the Invoke() method. In XP it works fine. In W7/Vista, it requires both IE and the target application to be "Run as Administrator" or else it generates the exception:
[Operation unavailable (Exception from HRESULT:0x8000401E3 MK_E_UNAVAILABLE))]
Here's the code:
private void _BtnPlace_onclick(IHTMLEventObje)
{
....
....
object AutoCADApp = null;
try
{
// Does not return the object from the Running Objects Table unless run 'As Administrator'
AutoCADApp = System.Runtime.InteropServices.Marshal.GetActiveObject("AutoCAD.Application");
}
catch (Exception ex)
{
MessageBox.Show("Unable to locate a running version of AutoCAD on this machine. Please make sure AutoCAD is running.\n\n [" + ex.Message + "]\n", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
object acadDoc = GetProperty(AutoCADApp, "ActiveDocument");
InvokeMethod(acadDoc, "SendCommand", keyin);
}
Any ideas on how to address the security issues to make this add-on run in W7/Vista (asking it to prompt for elevated privileges is ok)?
Maybe a shoot in the dark, but did you read this code project article:
http://www.codeproject.com/KB/vista-security/ElevatedPrivilegesDemand.aspx
A few points to think about:
Use early binding instead of reflection, invoking methods.
Check if some other code needing the 'Running As Administrator' privilege.
Try the .NET SendStringToExecute() instead.
Check if the command you were trying to invoke has some security
concerns.
Related
I am developing an application that supposed to run since the PC is starting (Windows 10 C# Windows Console App)
Therefore I use schtask to address it as follows:
schtasks /create /sc ONSTART /tn "RamanLocalServer" /tr "$INSTDIR\RamanLocalServer.exe" /ru System
schtasks /run /tn "RamanLocalServer"
This is a Rahman Server which has no UI at all (only console app)
This is my program located on TaskManager
Now, I want this Local server show notification to the user
---------------Attempt1:----------
According to C# How to Make a BalloonToolTip from a Non-Form Application It is possible to do that
However, since my program is located on Background Process, It shows no Balloontooltip
I wrap the code like this
private static void BalloonTip()
{
notifyIcon = new NotifyIcon();
notifyIcon.Icon = Properties.Resources.new_icon;
notifyIcon.Visible = true;
log.Debug("Balloon on server");
try
{
notifyIcon.ShowBalloonTip(600, "Rahman Updater", "New update is available\nGo to Rahman Manager to update", ToolTipIcon.Info);
}
catch (Exception e)
{
log.Error(e.Message);
log.Error(e.StackTrace);
throw;
}
}
The log file says nothing on exception
---------------Attempt2:----------
I Tried to use Toast as explained here https://learn.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification?view=winrt-20348
This is how I write the code
private static void CallToast()
{
log.Debug("Toast1");
try
{
//// Requires Microsoft.Toolkit.Uwp.Notifications NuGet package version 7.0 or greater
//new ToastContentBuilder()
.AddArgument("action", "viewConversation")
.AddArgument("conversationId", 9813)
.AddText("Guardian Updater")
.AddText("New update is available\nGo to Guardian Manager to update")
.Show(); // Not seeing the Show() method? Make sure you have version 7.0, and if you're using .NET 5, your TFM must be net5.0-windows10.0.17763.0 or greater
}
catch (Exception e)
{
log.Error(e.Message);
log.Error(e.StackTrace);
}
}
It shows this error on the log Access denied. (Exception occurred HRESULT: 0x80070005 (E_ACCESSDENIED)
However if I start the program by double click it like this, it works both for Toast/Balloon tooltip
According to the stackoverflow community (Sorry, I can't find the link), I learned that
In order to make it works (Toast/Balloon Tooltip), The code should be running on the UI thread
So my question is, Does it possible?
If not, are there any suggestion?
That was me who ask the question before my account on StackOverflow was somehow restarted
I solved that problem By:
Make a new Executable that responsible for the balloonTip
Let it run forever on tray (c# is able to do that)
To trigger that Executable, I register that program to Startup Program list
private bool StartSkript(string Systemskript)
{
Type typeFromProgID = Type.GetTypeFromProgID("xxx.application"); // this line works on windows 10 and doesnt work on windows server 2019.
if (typeFromProgID == null)
{
return false;
}
try
{
dynamic applicationInstance = Activator.CreateInstance(typeFromProgID);
applicationInstance.RunFormSkript(Systemskript, 0);
return true;
}
catch (Exception)
{
return false;
}
}
Hello,
we are trying to call a function in a running process. The above code finds xxx.application on the dev-machine with no trouble, but in the terminal server test-environment it returns null.
The app xxx is running under the same user as the c# program.
Our first problem is, that we dont really understand why we search for xxx.application (seems to be a class) instead of xxx.exe which would be the processes name.
Next, we dont know how to approach this. How do I check, if I am even looking for the right call "xxx.application"?
ProgID means the ProgramID of a COM-Server. Which is usually registered in the Windows registry after the component was installed.
This is kind of a code to indirectly create an instance of a COM class.
Its kind of an old technique that was heavily used in the 90ties and early 2000 years. ActiveX-Components are based on the COM technology.
Seems the COM-Server with ProgID "xxx.application" is not installed on the terminal server. Or not properly registered. Or your code hasn't enough privileges to read the relevant registry keys etc....
I have a windows desktop application written with C# (Windows forms). In the code, there is a part where I use a simple try-catch exception handler. It works as expected in desktops setting, however, when deployed in Citrix it does not work at all. There is an error that I expect to fire there, I catch it and the application keeps running just fine. Anyone seen anything like it?
EDIT:
This is the code that fails. It may not say much since it is just a try catch where I execute code that is related to a specific library.
try
{
if (this.model != null)
{
if (this.model.Context.GetService<Spotfire.Dxp.Application.Document>().ActivePageReference.ActiveVisualReference != (Spotfire.Dxp.Application.Visual)this.model.Visual)
{
this.model.Context.GetService<Spotfire.Dxp.Application.Document>().ActivePageReference.ActiveVisualReference = (Spotfire.Dxp.Application.Visual)this.model.Visual; //In certain conditions this line may fail, so I trap it.
}
}
}
catch (Exception exc)
{
//System.Diagnostics.Debug.WriteLine(exc.Source + " " + exc.Message + "\n" + exc.StackTrace);
}
I added a comment to the line that fails. I trap the error and it works just fine. The thing is that when it is deployed to citrix it fails to trap the error and it actually crashes the application. Thus my inclination to think that it is something related to citrix.
Thanks!
Good day!
I'm working on installer, which installs additional dependencies for my software using Process.Start.
foreach dependency:
var process = System.Diagnostics.Process.Start(processStartInfo);
process.WaitForExit();
The problem is when another msi installation is runned, WaitForExit hangs (and when I close this another msi installation, WaitForExit also exits).
I can't use timeouts, because dependencies are different with very different installation time.
Is there any ways to handle this situation and correctly kill process (actually I want to know is dependency is installing or just hanging)?
Many thanks.
Solution: in my case the problem is solved by checking if 'msiexec' process is running.
The solution to my problem - check global mutex, created by msiexec. This is also a correct way to check if another msi installation is running.
public static bool WaitAnotherMsiInstallation(int timeout)
{
const string MsiMutexName = "Global\\_MSIExecute";
try
{
using (var msiMutex = Mutex.OpenExisting(MsiMutexName, MutexRights.Synchronize))
{
return msiMutex.WaitOne(timeout);
}
}
catch (WaitHandleCannotBeOpenedException)
{
// The named mutex does not exist.
return true;
}
catch (ObjectDisposedException)
{
// Mutex was disposed between opening it and attempting to wait on it
return true;
}
}
Here is some details http://msdn.microsoft.com/en-us/library/aa372909(VS.85).aspx
My scenerio is connection to remote machine with C#.Net, and listing all processes with that remote computer. I can kill a process, or start a new process at remote. The problem is, when I execute a new process on remote, I can see the process on task manager, but it doesnt apeear on windows screen. Any idea why its not appearing on windows, but appearing on task manager/ process. Here is my execution code
private void btnStartNew_Click(object sender, EventArgs e)
{
object[] arrParams = { txtNewProcess.Text.Trim()};
try
{
manageClass = new ManagementClass(myScope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
manageClass.InvokeMethod("Create", arrParams);
btnConnect_Click(sender, e);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
My Scope is :
myScope = new ManagementScope(#"\ROOT\CIMV2", connOptions);
the problem is about administrator permissions
Shouldn't the ManagementPath be something like \ComputerName\Root\CIMV2 instead of just \ROOT\CIMV2 ?
If you have trouble with authentication, then you need to check the DCOM configuration on the target machine.
On the target machine, run dcomcnfg from the command prompt.
Expand Component Services\Computers\My Computer\DCOM Config
Find Windows Management Instruction, identified with GUID 8BC3F05E-D86B-11D0-A075-00C04FB68820 (you can see this in the details view).
Edit the properties and then add the username you are trying to login with under the permissions tab.
You may need to reboot the service for the changes to take effect.