I'm trying to write to the eventlog from a VSTO Outlook Plugin, but I haven't figured out how.
I've tried this a few different ways and I'm still not sure if I'm hitting a security permission issue between the Outlook plugin and the eventlog or something code related.
I tried with 2 different pieces of code. This is my testing piece and even it doesn't write:
EventLog myLog = new EventLog("Application");
myLog.Source = "ReportPhishing";
myLog.WriteEntry("Reporting Email");
This is the code I'm ultimately trying to add in:
string sourceName = "ReportPhishing";
//Defines who was the sender email
string SenderEmail = obj_CurrentItem.SenderEmailAddress;
//Defines who the end receiving email address is
string ReceiverEmail = obj_CurrentItem.ReceivedByName;
//Defines the schema used to pull the header information out of the email
string EmailHeaders = obj_CurrentItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E");
//Defines FileName as from the subject line
string FileName = obj_CurrentItem.Subject;
//Specifies the main event context
string eventSubject = "Reported Phishing Email";
//Creates the payload information for sending to the local eventlog
string eventPayload = eventSubject + "%n%nSenderEmail: " + SenderEmail + "%n%nReceivingEmail: " + ReceiverEmail + "%n%nSubject: " + FileName + "%n%nHeaders: " + EmailHeaders;
//string eventpayload = #"<EventData><Data Name=""SenderEmail"">"+ SenderEmail +"</Data><Data Name=""ReceivingEmail"">" + SenderEmail + "</Data><Data Name=""Subject"">" + FileName + "</Data><Data Name=""Headers"">" + EmailHeaders + "</Data></EventData>";
EventLog.WriteEntry(sourceName, eventPayload, EventLogEntryType.Error);
What I've tried:
I tried to create the event source from the plugin, but that never worked as it wouldn't execute without admin permissions.
I manually created the source via the registry, but that didn't seem to work either.
I removed the registry entry and created the source via an elevated command line using eventcreate. By creating it via commandline, I confirmed that a non-elevated command line could still write to the event source
Verified permissions from the Registry (I added a lot more permissions as a just in case)
Read through a number of other StackOverflow posts around the EventLog. None really discussed the plugin aspect. Most focused on permission issues or incorrect implementation of MS code examples.
Created a basic form application that created a log event. This appears to work with my above sample code:
There appears to be something within the VSTO Plugin functionality that prevents logging to the EventLog. I'm unsure where to go from here.
I want to create a remote desktop connection with C#. I found this question Run mstsc.exe with specified username and password.
At the moment I can create a new connection with username and password, but I want to change the path where the .rdp file will be saved.
Maybe you have an idea how I can change the save path.
Better that setting the default path, you can create the rdp file itself and save it in the default path.
the rdp file should contain the below content.
"full address:s:" + IP
"username:s:" + User
"domain:s:" + Domain
"password 51:b:" + Pass
"port:i:" + Port
"screen mode id:i:1"
"desktopwidth:i:800"
"desktopheight:i:600"
"session bpp:i:32"
"auto connect:i:1"
"autoreconnection enabled:i:1"
"compression:i:1"
"keyboardhook:i:2"
"audiomode:i:2"
"redirectdrives:i:1"
"redirectprinters:i:1"
"redirectcomports:i:0"
"redirectsmartcards:i:0"
"displayconnectionbar:i:1"
"alternate shell:s:"
"shell working directory:s:"
"disable wallpaper:i:1"
"disable full window drag:i:1"
"disable menu anims:i:1"
"disable themes:i:1"
"bitmapcachepersistenable:i:1";
As I come across issues when testing my current application, I often have to tweak the database the app uses. After losing important changes several times, I wrote a program that will back up my database to a file and then check the file into SubVersion. I have found that that backup application is not good enough.
The database is a PostgreSQL database, and my backup application invokes pg_dump to create the backup file. pg_dump is executed in a console window. When the database was on my own machine, it worked well. But when I moved the database to our test server, pg_dump asked for a password. While it's not that big a deal, I'd like to be able to supply the password automatically, since it is available in the backup application.
I've tried to follow advice I've found here, but pg_dump still stops and asks for a password. Here's the code that I thought should have supplied the password:
Process backupProcess = new Process();
backupProcess.StartInfo.UseShellExecute = false;
backupProcess.StartInfo.RedirectStandardInput = true;
backupProcess.StartInfo.FileName = dumpPath + "pg_dump.exe";
backupProcess.StartInfo.Arguments = " --host " + host +
" --port " + port +
" --username " + userName +
" --format custom --blobs --verbose --file " +
"\"" + txtBackupFile.Text + "\" " + dbName;
backupProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
backupProcess.Start();
StreamWriter standardInput = backupProcess.StandardInput;
standardInput.WriteLine("mypassword");
backupProcess.WaitForExit();// Waits here for the process to exit.
Thank you for your help.
RobR
I have solved this by using
backupProcess.EnvironmentVariables["PGPASSWORD"] = "password";
This way, I avoid the password will be stored on the computer
Maybe it's cheating a little bit (in the sense that it doesn't really help you answer the question of how to feed input to pg_dump), but you could refer to this answer which suggests the use of a .pgpass file. It would certainly be possible to write to this file dynamically rather than try to interact with the program once it prompts.
Info on .pgpass here.
This is a possible duplicate. Couldn't find the exact one, I remember going through one such long time back.
The tool needs a capability to detect if any MS Word file is opened anywhere from the computer. So we use a process watcher, like this:
string query = "SELECT TargetInstance FROM __Instance" + Event + "Event WITHIN 0.5 " +
"WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = '" + processName + "'";
string scope = #"\\.\root\CIMV2";
//Create a watcher and listen for events
watcher = new ManagementEventWatcher(scope, query);
watcher.EventArrived += eventHandler;
watcher.Start();
Now whatever that is, here is the tricky part: I need to get the word automation instance of the currently opened WINWORD process. So I use Marshal.GetActiveObject to get the running instance. But an opened Word application gets registered in the running object table only if the word app loses focus (as documented by msdn). How do I manually register the word application in ROT if I have the process with me? Some pseudo code below
//process started
private void ProcessStarted(object sender, EventArrivedEventArgs e)
{
// Marshal.GetActiveObject fails since there is no object yet.
// Process.GetProcessesByName("WINWORD") got it.
// now how to register this word process to ROT?
// so that I have a global instance of word application?
}
Note: I can with some heavy API calls programmatically force focus away from opened word window and then bring it back, but thats a complete mess.
Any normal way of registering?
As far as I know there is no way to register another application's objects in the ROT without its direct cooperation. The table doesn't track processes, it tracks class factories and their associated monikers. In order to register something in the ROT you need its IUnknown pointer, which is not something you're going to get from Word directly.
How can I make my C# app erase itself (self-destruct)? Here's two ways that I think might work:
Supply another program that deletes the main program. How is this deleter program deleted then, though?
Create a process to CMD that waits a few seconds then deletes your file. During those few seconds, you close your application.
Both of those methods seem inefficient. I have a feeling that there's some built-in flag or something in Windows that allows for such stuff. How should I do it? Also, can you provide some sample code?
UPDATE: Thanks for all your answers! I'm going to try them, and see where that gets me.
First of all, some people have asked why I'd want my app to do this. Here's the answer: a few days ago, I read the Project Aardvark spec that Joel Spolsky posted on his blog, and it mentioned that the client app would delete itself after the remote session. I'm wondering how this works, and how, if I ever need to do this, I can accomplish such a feat.
Here's a little overview of what's been suggested:
Create a registry entry that tells Windows to delete the file on reboot
Launch CMD with a ping command to wait a few seconds and then delete the file
Both of those, of course, have their disadvantages, as outlined in the comments.
However, would such a method as outlined below work?
There are two executables: Program.exe and Cleaner.exe. The former is the program itself, the latter is the app that deletes Program.exe and itself (if it's loaded into memory, as I'm about to explain). Is it possible for Program.exe (which has dependencies) to load all of Cleaner.exe, which doesn't have any dependencies, into memory and run it?
If this is possible, could Cleaner.exe be packaged inside Program.exe, loaded into memory, and run?
There's a MoveFileEx API, which, when given a MOVEFILE_DELAY_UNTIL_REBOOT flag, will delete specified file on next system startup.
There's a great CodeProject Article about this topic.
Edit: Basically it's a simple cmd-call which will delete the specified files after some seconds.
Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + Application.ExecutablePath);
Application.Exit();
You will never be able to guarantee that this will work, as long as you require a physical presence on the machine. For example:
What if the app fails to release a resource in a timely fashion while you're trying to delete it? An error occurs, and the app remains.
The behavior of one app starting another which then deletes the first app is very suspicious from an AV perspective. You are likely to trigger defenses on a user's machine which may kill the process that's trying to kill your original app.
If you do something like delete a file at reboot, what if the user moves your file in between or makes a copy? It's not in the original spot anymore, and the app remains.
If your application requires this level of security, consider hosting it on a machine you control (e.g., by providing a web service and letting a stub client access it that way).
On a somewhat related note, one is also tempted to speculate about the motives of someone who (1) requires a physical presence on someone's machine and (2) wants to delete the evidence that the app existed.
A correction to #Bobby answer, in case people will find it useful - executable path needs to be quoted. Additionally, below is setting cmd.exe window to be hidden (otherwise it flashes as a black console window) and converted to run without relying on System.Windows.Forms assembly (the Application class).
var exepath = Assembly.GetEntryAssembly().Location;
var info = new ProcessStartInfo("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del \"" + exepath + "\"");
info.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(info).Dispose();
Environment.Exit(0);
There is also FileOptions.DeleteOnClose, but that requires the file to be open for writing. You might be able to do it with a sequence like this (untested):
Program launches as Original.exe, and detects (from its own name) that it needs to trigger the self-destruct function.
Original.exe creates a new file Temp.exe with FileOptions.DeleteOnClose and copies its own content into it, but does not close it yet
Original.exe opens a second, read-only handle to Temp.exe and closes the first write handle. The read-only handle can co-exist with an execute handle, whilst keeping the file open to delay auto-deletion.
Original.exe launches Temp.exe. Temp.exe detects that it has been launched from the temp directory and bypasses the self-destruct sequence and continues normal operation.
Original.exe exits (taking its read-only handle to Temp.exe with it.)
Temp.exe continues running. When it exits, the file Temp.exe will no longer be in use so it will be deleted automatically.
Edit #2: Actually I don't think this is possible, because it relies on the kernel opening the file with the FILE_SHARE_DELETE flag, which is unlikely.
sorted by NJ
c#
the other codes does not work so its simple
if u create bath file that loops to del application and
the batch file itself
u can use takkill command to kill the process if u dont want to use
application.close method
`string delname = "test.cmd";
string fileurl = Application.ExecutablePath;
System.IO.StreamWriter file = new System.IO.StreamWriter(delname);
file.WriteLine(":Repeat");
file.WriteLine("del \"" + fileurl + "\"");
file.WriteLine("if exist \"" + fileurl + "\" goto Repeat");
file.WriteLine("del \"" + delname + "\"");
file.Close();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.FileName = delname;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(startInfo);`
`
Th3 3e3 one is not 3d parts ov one
I5
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Think CMD
int sectosleep = 5000;
string exename = "yourexe.exe";
string location = #"c:\yourexe.exe"
Process.Start("cmd.exe", "/C taskkill /f /im " + exename + " & ping 1.1.1.1 -n 1 -w " + sectosleep + " > Nul & Del /F /Q \"" + location + "\"");
;>
I know reflector deletes itself if you use an old version and choose not to update. You might try to figure out what it does. I would start with FileMon and see if it spawns any processes to achieve this.
Since my application (a Windows Service) is installed via the Windows Installer, I self-delete using this:
Dim uninstall_params As String = "/x {MY-PRODUCTS-GUID} /qn /norestart REBOOT=ReallySuppress"
proc.StartInfo = New ProcessStartInfo("msiexec.exe", uninstall_params)
proc.Start()
Environment.Exit(-1)
Sorry--it's in VB, but it should be easily convertible to C#.
Works in Windows 7 & 8, **ENSURE you run your application with admin privileges or you will get an error.
This code exists elsewhere so I can't take full credit I found I made it work for me by adding "Application.Exit();"
static void autodelete()
{
string batchCommands = string.Empty;
string exeFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", string.Empty).Replace("/", "\\");
batchCommands += "#ECHO OFF\n"; // Do not show any output
batchCommands += "ping 127.0.0.1 > nul\n"; // Wait approximately 4 seconds (so that the process is already terminated)
batchCommands += "echo j | del /F "; // Delete the executeable
batchCommands += exeFileName + "\n";
batchCommands += "echo j | del deleteMyProgram.bat"; // Delete this bat file
File.WriteAllText("deleteMyProgram.bat", batchCommands);
Process.Start("deleteMyProgram.bat");
Application.Exit();
}
This is the Uninstall.exe:
Shutdown.
Wait for 3 sec.
Try to kill that task if it is still running.
Wait for 3 sec.
Delete the app directory with the Uninstall.exe in it.
public void Uninstall()
{
var delPath = AppDomain.CurrentDomain.BaseDirectory;
var procId = Process.GetCurrentProcess().Id;
var psi = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/C timeout 3 & Taskkill /F /PID {procId} & timeout 3 & rd /s /q \"{delPath}\"",
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
};
Process.Start(psi);
Application.Current.Shutdown();
}