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.
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
I know this question was already asked, but I couldn't find the solution so far.
What I'm trying to do is uninstall a windows service and delete the folder with the windows service using C#.
Windows service uninstall
public static void Uninstall(string exeFilename)
{
var commandLineOptions = new string[1] { "/LogFile=uninstall.log" };
if (!Directory.Exists(exeFilename)) return;
var fileNames = Directory.GetFiles(exeFilename);
var serviceFile = fileNames.FirstOrDefault(f => f.EndsWith(".exe"));
var serviceFileName = Path.GetFileName(serviceFile);
var serviceName = Path.GetFileNameWithoutExtension(serviceFile);
var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);
if (!serviceExists) return;
var installer =
new AssemblyInstaller($"{exeFilename}\\{serviceFileName}", commandLineOptions)
{
UseNewContext = true
};
installer.Uninstall(null);
installer.Dispose();
}
Folder and files delete
public static void DeleteFolder(string folderPath)
{
if(!Directory.Exists(folderPath)) return;
try
{
foreach (var folder in Directory.GetDirectories(folderPath))
{
DeleteFolder(folder);
}
foreach (var file in Directory.GetFiles(folderPath))
{
var pPath = Path.Combine(folderPath, file);
File.SetAttributes(pPath, FileAttributes.Normal);
File.Delete(file);
}
Directory.Delete(folderPath);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
Error that I get
Access to the path 'c:\services\x\x.exe' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.IO.File.Delete(String path)
This error occurs randomly. The .exe file is not readonly, sometimes the files get deleted.
Does anyone know what's wrong?
Stopping a Windows service does not equate to exiting a process. An executable can house multiple Windows services (it's essentially the physical shell for the services).
So what you're running into, it looks like, is that the service likely stopped just fine, and uninstall can proceed and the deletion of files can proceed, but only up until the point where it reaches the executable, which hasn't yet had a chance to exit.
Stopping, exiting, uninstalling are all asynchronous and need time to complete before moving to the next step.
What you have to do is follow this formula
Ensure your code is running with elevated privileges if you can; if you can't you may run into Access Denied. You can also try changing the ownership of the target executable.
Stop or ensure the service is stopped. If there are multiple services, stop all of them.
Wait for stop to actually occur. It's not always immediate.
Call the Uninstall().
Wait some amount of time. Check to see if the process is running. If it is you will call Process.Kill() (see an implementation below).
Finally, you can call the DeleteFolder() for which your implementation looks adequate to me.
Exiting the Process
Write a method that looks something like this. You might want to tweak it.
void Exit(Process p)
{
for (int i = 0; i <= 5; i++)
{
// doesn't block
if (p.HasExited) return;
// doesn't block; pass true to terminate children (if any)
p.Kill(true);
// wait 5 seconds then try again
Thread.Sleep(5000);
}
}
After all that you should be good to go.
Is the service stopped / executable stopped and does the program have Administrator access? If you don't have administrator access, refer to:
How do I force my .NET application to run as administrator?
to run as administrator. When uninstalling a program, administrator permissions are almost always required. If this still fails, you are not the owner of the file and you must change the owner to yourself or Administrators. You can do this programatically here: Getting / setting file owner in C#
I think you have to stop the service first.
try using
sc stop <service name>
to stop the service.
Then uninstall should work.
try using installutil.exe if your uninstall code does not work. It can give your error output also.
The exe cannot be deleted if it is currently executing so make sure exe is not executing when you try to delete it.
You can use setup project, it generates the uninstaller automatically and gives you a range of possibilities with it.
Example of the service installer
You must download the addon in the market place
I do not want to used the default behavior of ClickOnce, which presents a dialog window, checking for updates, I want to check for update manually
After search on the internet I found:
try
{
var deploy = ApplicationDeployment.CurrentDeployment;
if (deploy.CheckForUpdate())
MessageBox.Show("There is a new update");
else
MessageBox.Show("You using the latest version");
}
catch (Exception e2)
{
MessageBox.Show(e2.ToString());
}
When I install the application and want to check for update I got the error:
system.deployment.application.trustnotgrantedexception: user has refused to grant required permissions to the application
Could you help please.
Thanks in advance.
Right Click on your project. Select Properties. Then go to publish Tab. Click updates. Then uncheck "The application should check for updates".
I'm not really sure why you are getting that error, but I'm also using the same approach. Checking manually for updates. But my application is deployed on a server. I have this timer that checks for new updates every 15 mins.
Here's how I do it.
private void InstallUpdateSyncWithInfo()
{
if (!isNewUpdateMessageShown)
{
try
{
if (ApplicationDeployment.IsNetworkDeployed)
{
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
ad.UpdateCompleted += new AsyncCompletedEventHandler(ad_UpdateCompleted);
//ad_UpdateCompleted is a private method which handles what happens after the update is done
UpdateCheckInfo info = ad.CheckForDetailedUpdate();
if (info.UpdateAvailable)
{
//You can create a dialog or message that prompts the user that there's an update. Make sure the user knows that your are updating the application.
ad.UpdateAsync();//Updates the application asynchronously
}
}
}
catch (Exception ex)
{
ex.Log();
}
}
}
void ad_UpdateCompleted(object sender, AsyncCompletedEventArgs e)
{
//Do something after the update. Maybe restart the application in order for the update to take effect.
}
EDIT
I have updated my answer. You can copy and paste this one and adjust it based on your app needs.
On my previous answer, I'm opening a new window that tells the users that there's an update then have the user choose if he or she wants to update the application.
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.
I have two windows application, one is a windows service which create EventWaitHandle and wait for it. Second application is a windows gui which open it by calling EventWaitHandle.OpenExisting() and try to Set the event. But I am getting an exception in OpenExisting. The Exception is "Access to the path is denied".
windows Service code
EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset, "MyEventName");
wh.WaitOne();
Windows GUI code
try
{
EventWaitHandle wh = EventWaitHandle.OpenExisting("MyEventName");
wh.Set();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
I tried the same code with two sample console application, it was working fine.
You need to use the version of the EventWaitHandle constructor that takes an EventWaitHandleSecurity instance. For example, the following code should work (it's not tested, but hopefully will get you started):
// create a rule that allows anybody in the "Users" group to synchronise with us
var users = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
var rule = new EventWaitHandleAccessRule(users, EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify,
AccessControlType.Allow);
var security = new EventWaitHandleSecurity();
security.AddAccessRule(rule);
bool created;
var wh = new EventWaitHandle(false, EventResetMode.AutoReset, "MyEventName", out created, security);
...
Also, if you're running on Vista or later, you need to create the event in the global namespace (that is, prefix the name with "Global\"). You'd also have to do this on Windows XP if you use the "Fast User Switching" feature.
This might be caused by the service process running at an elevated privilege level, but the GUI process is not. If you put the same code into two console apps, they'll both be running at user level and won't have any trouble accessing each other's named shared objects.
Try running the GUI app with the "Run as administrator" flag from the Windows start menu. If that solves the issue, you need to read up on how to request elevation within your code. (I haven't done that)