Best windows questions in October 2011

How do I detect if a drive has a recycle bin in C#?

12 votes

I have an application which uses the FOF_ALLOWUNDO with SHFileOperation in order to move files to the recycle bin.

Some removable drives do not have a recycle bin. In this case SHFileOperation deletes the files directly. I want to give a warning to the user that the files are going to be deleted directly.

In order to do this I need to know if the drive has a recycle bin.

I found a function called SHQueryRecycleBin when I looked at the functions exported by shell32.dll.

If the drive specified in pszRootPath has a recycle bin the function returns 0 otherwise it returns -2147467259.

I'm going to use this function via PInvoke.

I used the P/Invoke Interop Assistant to create the PInvoke code.

Here is the code of my function DriveHasRecycleBin:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    private struct SHQUERYRBINFO
    {
        /// DWORD->unsigned int
        public uint cbSize;

        /// __int64
        public long i64Size;

        /// __int64
        public long i64NumItems;
    }

    /// Return Type: HRESULT->LONG->int
    ///pszRootPath: LPCTSTR->LPCWSTR->WCHAR*
    ///pSHQueryRBInfo: LPSHQUERYRBINFO->_SHQUERYRBINFO*
    [System.Runtime.InteropServices.DllImportAttribute("shell32.dll", EntryPoint = "SHQueryRecycleBinW")]
    private static extern int SHQueryRecycleBinW([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPTStr)] string pszRootPath, ref SHQUERYRBINFO pSHQueryRBInfo);

    public bool DriveHasRecycleBin(string Drive)
    {
        SHQUERYRBINFO Info = new SHQUERYRBINFO();
        Info.cbSize = 20; //sizeof(SHQUERYRBINFO)
        return SHQueryRecycleBinW(Drive, ref Info) == 0;
    }

C# - Programmatically change the Windows Shell

8 votes

I'm working on a project that will be "embedded" into a Windows 7 system, this is going to be achieved by disabling task manager and changing the windows shell to the application, as well as other things.

What I'm looking to do here is programmatically change the Windows shell between the application and explorer.exe, I would like to know if there's any way to do this in C#.

Currently I have a few lines of code that attempt to change the registry entry for the Windows Shell, but nothing appears to happen after refreshing the Registry Editor, the code looks like this:

    regKey = Registry.LocalMachine.OpenSubKey("SOFTWARE", true).OpenSubKey("Microsoft", true).OpenSubKey("Windows NT", true).OpenSubKey("CurrentVersion", true).OpenSubKey("Winlogon", true);
    regKey.DeleteValue("Shell");
    regKey.SetValue("Shell", shell);
    regKey.Close();

I've tried restarting windows to see if that allows the shell change to complete, but to no avail.

I'd greatly appreciate it if someone can tell me if it's even possible to do it programmatically, and where I'm going wrong with it.

Also, I'd be grateful to know if there's a way to code the program so that it's always running with admin privileges so that registry editing will work.

Many Thanks,

Richard

After much searching of other locations on the net, I have finally got the Shell to change to the executable file of the application that is being built.

The "Embedding" process is a three step process, in the case of the software I'm working on, we start by disabling Task Manager, We then set the shell executable in the Local Machine registry and then repeat the process in the Current User registry.

Below is the code that achieves this:

public void embedSoftware()
{
    try
    {
        // Disable Task Manager
        regKey = Registry.CurrentUser.OpenSubKey(subKey, true).CreateSubKey("System");
        regKey.SetValue("DisableTaskMgr", 1);
        regKey.Close();
        // Change the Local Machine shell executable
        regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
        regKey.SetValue("Shell", shell, RegistryValueKind.String);
        regKey.Close();
        // Create the Shell executable Registry entry for Current User
        regKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
        regKey.SetValue("Shell", shell);
        regKey.Close();
        MessageBox.Show("Embedding Complete");

    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
    }
}

In this example the variable "shell" is a string containing the path of the executable to use as the new Windows Shell.

Further to this there's a method to "un-embed" the software, this method simply deletes the "DisableTaskMgr" and "Shell" values from the Current User registries, it also resets the "Shell" value in the Local Machine registry to "explorer.exe".

I hope this helps others out there who're having trouble changing Windows Shells programmatically.

Regards,

Richard

How to get total memory in bytes used by OpenGL in C++?

7 votes

How to get total memory in bytes used by OpenGL in C++?

I'm building an OpenGL application and the total memory used seems to be rising, I can get the info about the total memory used by variables & objects created by myself but can't guarantee how much memory OpenGL is using for its variables & objects & textures, etc. So is it possible to get the total memory in bytes used by OpenGL in C++?

In general, you don't. OpenGL is ultimately a hardware abstraction. And OpenGL simply doesn't provide a way to get that sort of information.

There are vendor-specific extensions that will give you ways to ask, though what you get back depends on the architecture. AMD hardware provides the ATI_meminfo extension. It breaks memory down into types of objects: buffer objects, textures, and renderbuffers.

NVIDIA provides the experimental extension NVX_gpu_memory_info. There's no information in the registry about how to use it, so I can't link you to anything.

In any case, the most effective way to know what the GPU is using is to just keep track of it yourself. Always use internal image formats with sizes; this means you can compute a pretty good estimate of how much memory a texture takes up. The same goes for buffer objects and so forth.

You won't get exact numbers, as padding, alignment, and the like can confound you. But you'll get something pretty decent.

Is there a way to convert a System.IO.Stream to a Windows.Storage.Streams.IRandomAccessStream?

7 votes

In Windows 8; I would like to pass the contents of a MemoryStream to a class that accepts a parameter of type Windows.Storage.Streams.IRandomAccessStream. Is there any way to convert this MemoryStream to an IRandomAccessStream?

Found a more elegant solution:


public static class MicrosoftStreamExtensions
    {
    public static IRandomAccessStream AsRandomAccessStream(this Stream stream) {
        return new RandomStream(stream);
    }
    }
    class RandomStream : IRandomAccessStream
    {
        Stream internstream;
        public RandomStream(Stream underlyingstream)
        {
            internstream = underlyingstream;
        }
        public IInputStream GetInputStreamAt(ulong position)
        {
            //THANKS Microsoft! This is GREATLY appreciated!
            internstream.Position = (long)position;
            return internstream.AsInputStream();
        }

        public IOutputStream GetOutputStreamAt(ulong position)
        {
            internstream.Position = (long)position;
            return internstream.AsOutputStream();
        }

        public ulong Size
        {
            get
            {
                return (ulong)internstream.Length;
            }
            set
            {
                internstream.SetLength((long)value);
            }
        }
    }

Perl: how to portably reserve a TCP port (so there will be a non-available URL)

7 votes

I'm the maintainer of the XML-LibXSLT module and one of the tests needs to access a non-existing URL. Problem was that someone reported that on their system the URL existed, so I decided to allocate a random port on localhost where I'm sure there will be no web-service. It was done like that:

# We reserve a random port to make sure the localhost address is not
# valid. See:
#
# https://rt.cpan.org/Ticket/Display.html?id=52422

my $sock = IO::Socket::INET->new(
    Proto => 'tcp',
);

my $port = $sock->sockport();

$file = "http://localhost:${port}/allow.xml";

Now, the problem is that $port is defined and valid (to the value of a reserved port) on Linux, but it does not appear to work on Windows - see this bug report - https://rt.cpan.org/Ticket/Display.html?id=71456 . My question is: how can I reserve a new, random, not-yet-occupied port portably across UNIXes, Mac OS X and Windows in Perl 5?

Regards,

Shlomi Fish

You should be able to bind to the loopback address using port 0 (so that a port will be allocated to you). For bonus points you may want to try to connect the socket to itself (probably not needed anywhere, but should guarantee that it has an address)

reading windows font

7 votes

What is the best way to read all windows fonts into ComboBox? Basically, I'm tried do this:

equal to the Microsoft Word

I can do:

 string[] fonts = Directory.GetFiles(@"C:\windows\fonts");

and show each file into ComboBox, but this is correct? Have not an component that do this work?

Thanks in advance.

Try this:

using System.Drawing.Text;

InstalledFontCollection myFonts = new InstalledFontCollection();
foreach (FontFamily ff in myFonts.Families)
  comboBox1.Items.Add(ff.Name);
}

How to read title and id from Blu-ray disc?

6 votes

Is it somehow possible to fetch Blu-Ray Disc id and title programmatically on Windows7+ platform?

If you can programmatically open the following files you'll probably get what you need:

/AACS/mcmf.xml - This file is the Managed Copy manifest file and will contain a 'contentID' attribute (in the mcmfManifest tag) that can be used to identify the disc. Typically it is a 32 hexadecimal digit string.

There is sometimes, also an /CERTIFICATE/id.bdmv file which contains a 4 byte disc organization id (at byte offset 40) followed by a 16 byte disc id.

Sometimes, there is metadata information in the /BDMV/META/DL directory in the XML file bdmt_eng.xml (replace eng for other 3 letter language codes for other languages). For example on the supplemetary disc of The Dark Knight I see this file contains:

<di:title><di:name>The Dark Knight Bonus Disc</di:name></di:title>

C++ printf with %f but localized for the user's country

6 votes

I'm using the following C++ syntax to output a floating point value on a Windows platform:

printf("%.2f", 1.5);

It works well if I run it on an English user account. My assumption was that if I run it on, say French user account, the output will be 1,50 instead of 1.50.

Why do I not see it and how to produce my desired result?

The radix character (i.e. '.' or ',') is defined by the current locale. The default locale (at least for Windows systems) is "C", which defines '.' as radix character.

You can set the current locale for a C/C++ program using the setlocale function.

To set the locale to the current system/user locale, you can use the following statement:

#include <locale.h>
setlocale(LC_ALL, ".OCP");

See here (cf. the examples on the linked page...) for more information about setlocale

Windows vs. Linux GCC argv[0] value

6 votes

I'm programming on Windows using MinGW, gcc 4.4.3. When I use the main function like this:

int main(int argc, char* argv[]){
    cout << "path is " << argv[0] << endl;
}

On Windows I get a full path like this: "C:/dev/stuff/bin/Test". When I run the same application on Linux, however, I get some sort of relative path: "bin/Test". It's breaking my application! Any idea on how to make sure the path is absolute on both systems?

No, there isn't. Under most shells on Linux, argv[0] contains exactly what the user typed to run the binary. This allows binaries to do different things depending on what the user types.

For example, a program with several different command-line commands may install the binary once, and then hard-link the various different commands to the same binary. For example, on my system:

$ ls -l /usr/bin/git*
-rwxr-xr-x  109 root  wheel  2500640 16 May 18:44 /usr/bin/git
-rwxr-xr-x    2 root  wheel   121453 16 May 18:43 /usr/bin/git-cvsserver
-rwxr-xr-x  109 root  wheel  2500640 16 May 18:44 /usr/bin/git-receive-pack
-rwxr-xr-x    2 root  wheel  1021264 16 May 18:44 /usr/bin/git-shell
-rwxr-xr-x  109 root  wheel  2500640 16 May 18:44 /usr/bin/git-upload-archive
-rwxr-xr-x    2 root  wheel  1042560 16 May 18:44 /usr/bin/git-upload-pack
-rwxr-xr-x    1 root  wheel   323897 16 May 18:43 /usr/bin/gitk

Notice how some of these files have exactly the same size. More investigation reveals:

$ stat /usr/bin/git
234881026 459240 -rwxr-xr-x 109 root wheel 0 2500640 "Oct 29 08:51:50 2011" "May 16 18:44:05 2011" "Jul 26 20:28:29 2011" "May 16 18:44:05 2011" 4096 4888 0 /usr/bin/git
$ stat /usr/bin/git-receive-pack 
234881026 459240 -rwxr-xr-x 109 root wheel 0 2500640 "Oct 29 08:51:50 2011" "May 16 18:44:05 2011" "Jul 26 20:28:29 2011" "May 16 18:44:05 2011" 4096 4888 0 /usr/bin/git-receive-pack

The inode number (459240) is identical and so these are two links to the same file on disk. When run, the binary uses the contents of argv[0] to determine which function to execute. You can see this (sort of) in the code for Git's main().

What is the best API to combine C++11 async/futures with Windows asynchronous IO?

5 votes

Especially the upcoming Windows 8 (with Metro) will require that any IO is programmed asynchronously. In C#/.Net there seems to be special await and such like constructs for that and the JavaScript API will have its own mechanism for that to work.

What will be the C++11-integration for that? Is the a concise example (eg. reading an image from a file for display?) for modern (or upcoming) Windows? If it's using C++11 features I would expect that async or future is involved?

The Tips and tricks for developing Metro style apps using C++ presentation covers this at 59:13. The raw interface uses callback objects. In practice, people are likely to use the simplified interface offered by PPL.

Download Windows Updates Using C#

5 votes

Is there any way to Download updates of windows programmatic using c#. (Then we can manage it)

The Windows Update API is documented here. A quick stackoverflow search has convinced me that you can indeed use COM from C# so this should solve your problem.

I also have some sample code, not in C#, but it may give you a head start in understanding how the interfaces can be used.