ASpeak IOpine!

Mark File for deletion on reboot

Posted on March 24, 2009

Requirement: Delete files from a given folder using C#.

Challenge: The file may be in use i.e. locked.

Approach: Use System Call to mark file for deletion on restart

Solution: Use PInvoke for MoveFileEx.

///
/// Consts defined in WINBASE.H
///
internal enum MoveFileFlags
{
    MOVEFILE_REPLACE_EXISTING = 1,
    MOVEFILE_COPY_ALLOWED = 2,
    MOVEFILE_DELAY_UNTIL_REBOOT = 4,
    MOVEFILE_WRITE_THROUGH  = 8
}
 
 
/// <summary>
/// Marks the file for deletion during next system reboot
/// </summary>
/// <param name="lpExistingFileName">The current name of the file or directory on the local computer.</param>
/// <param name="lpNewFileName">The new name of the file or directory on the local computer.</param>
/// <param name="dwFlags">MoveFileFlags</param>
/// <returns>bool</returns>
/// <remarks>http://msdn.microsoft.com/en-us/library/aa365240(VS.85).aspx</remarks>
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll",EntryPoint="MoveFileEx")]
internal static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName,
MoveFileFlags dwFlags);
 
//Usage for marking the file to delete on reboot
MoveFileEx(fileToDelete, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);

The file is marked for deletion in registry in following location

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerPendingFileRenameOperations

Uninstallation from C#

Posted on March 17, 2009

I wanted to programatically uninstall an application installed in my system. Following code is a working piece to uninstall any custom application from the system.

Note: Following code snippet is not the best example of good coding standards ! It was just a sample I was trying to use to achieve something. The code is a mixture of coding styles lifted across various sites. Please excuse for that :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
private static int Uninstall()
{
        Microsoft.Win32.RegistryKey Fregistry =
        Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE")
        .OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion")
        .OpenSubKey("Installer").OpenSubKey("UserData")
        .OpenSubKey("S-1-5-18").OpenSubKey("Products");
        string[] Names = Fregistry.GetSubKeyNames();
        string uninstall = "";
        string ApplicationName = "My Custom Application";
        for (int i = 0; i < Names.Length; i++)
        {
            Microsoft.Win32.RegistryKey FTemp = Fregistry.OpenSubKey(Names[i]).OpenSubKey("InstallProperties");
            if (FTemp == null)
                continue;
            string appFound = (FTemp.GetValue("DisplayName") == null) ? String.Empty : FTemp.GetValue("DisplayName").ToString();
            if (!String.IsNullOrEmpty(appFound))
                System.Diagnostics.Trace.WriteLine("Found Software: " + appFound);
            if (String.Compare(appFound, ApplicationName, true) == 0)
            {
                String installedVersion = FTemp.GetValue("DisplayVersion").ToString();
                if (!installedVersion.StartsWith("3.1."))//can be removed if only one version is installed
                    continue;
                object obj = FTemp.GetValue("UninstallString");
                if (obj == null)
                    uninstall = "";
                else
                    uninstall = obj.ToString();
                i = Names.Length;
            }
        }
        if (String.IsNullOrEmpty(uninstall))
        {
            return -1;
        }
        System.Console.WriteLine(uninstall);
        System.Diagnostics.Process FProcess = new System.Diagnostics.Process();
        string temp = "/passive /x{" + uninstall.Split("/".ToCharArray())[1].Split("I{".ToCharArray())[2];
        FProcess.StartInfo.FileName = uninstall.Split("/".ToCharArray())[0];
        FProcess.StartInfo.Arguments = temp;
        FProcess.StartInfo.UseShellExecute = false;
        FProcess.Start();
        FProcess.WaitForExit();
        if (FProcess.ExitCode != 0)
            return -1;
        else
        {
            return 0;
        }
}
Tagged as: , No Comments

Remote Debugging with VS2008

Posted on December 4, 2008
Remote Debugging

Remote Debugging

This is a very common development requirement and many of you might be knowing this thing already. However, I am just putting this information as it might help someone. In a distributed development scenario it becomes imminent to have remote debugging possible lest you have your development environment both on your regular development system and the remote server where the webapp is deployed. However, this problem could be resolved if we try to use remote debugging. It is easy to do with Visual Studio.NET. I am using VS2008 but the same should apply to 2005 as well with minor changes.

All you need to do is to copy C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\Remote Debugger\ folder from your local development system having VS2008 to the remote system which you want to debug. On remote system you can launch msvsmon.exe and also you can create a desktop shortcut for the same to make it easy to launch everytime. The user launching this app must be an admin to provide full previledges else you should use run as to launch this application with administrator rights.

More information could be found from
http://www.wictorwilen.se/Post/How-to-get-Remote-Debugging-work-properly.aspx

MSDN code examples could be incorrect as well

Posted on September 8, 2008

It was really odd for me to find an error in MSDN code example which took almost a couple of hours to figure out what is wrong. I am working in VSTO (Visual Studio Tool for Office). I am developing a plugin which is suppose to override some of the specific Office 2007 functionalities and implement some custom actions. My quest for knowledge took me here. I found this page very interesting and I found the explanation for exactly what was required. I took the C# code example as it is and tried to play around in my own sample. Sadly, the example which is given on the page in C# has a flaw.

public void mySave(IRibbonControl control, bool cancelDefault)
{
    If (repurposing)
    {
        MessageBox.Show("The Save button has been temporarily repurposed.");
        cancelDefault = False;
    }
    else
    {
        cancelDefault = False;
    }
}

In this code example, the second parameter should be a reference type. Visual basic example in the same MSDN page shows it correctly but the C# example as given above is incorrect. I respect MSDN so much that I didn't care to see if anything is wrong in the code I lifted. After fiddeling around with a number of things and learning a whole lot than intended, I found the problem.
Lesson learnt! I will be more careful from next time :)

Microsoft .NET Framework 3.5 SP1 Source Code Released

Posted on August 31, 2008

I would have never known that this takes up these many calls to perform a simple Console.WriteLine operation unless Microsoft had released the source code of the .net framework. I am delighted that the source code for 3.5 sp1 is out. It is time to dive deep in the framework itself.

Find the link below:

http://blogs.msdn.com/rscc/archive/2008/08/28/net-framework-3-5-sp1-sources-are-available.aspx