Télécharger la source du .NET depuis ReferenceSource et rechercher dans tous les fichiers UnsafeNativeMethods.cs
ou dans le fichier win32native.cs
. Il y a presque tous les API Windows.
Ne pas utiliser IntPtr
mais HandleRef
pour les paramètres de type HWND
selon la MSDN
.
IntPtr iptr = ...; HandleRef href = new HandleRef(null, iptr);
IntPtr, SafeHandle and HandleRef - Explained Archive du 08/02/2009 le 28/04/2020
SafeHandle and HandleRef Archive du 07/12/2014 le 28/04/2020
Utiliser string
à la place en spécifiant le Marshal
pour chaque paramètre.
public static extern IntPtr FindWindowA([MarshalAs(UnmanagedType.LPStr)] string className, [MarshalAs(UnmanagedType.LPStr)] string windowName);
Il est aussi possible de mettre directement DllImport(CharSet = CharSet.Ansi)
ou CharSet.Unicode
mais l'analyseur statique de Visual Studio préfère l'utilisation de MarshalAs
.
Si CharSet.Ansi
est utilisé, il est préférable de rajouter DllImport(BestFitMapping = false, ThrowOnUnmappableChar = true)
.
Ne marche qu'à partir de Windows Vista.
Get drive label in C# Archive du 16/05/2010 le 28/04/2020
public const string SHELL = "shell32.dll"; [DllImport(SHELL, CharSet = CharSet.Unicode)] public static extern uint SHParseDisplayName(string pszName, IntPtr zero, [Out] out IntPtr ppidl, uint sfgaoIn, [Out] out uint psfgaoOut); [DllImport(SHELL, CharSet = CharSet.Unicode)] public static extern uint SHGetNameFromIDList(IntPtr pidl, SIGDN sigdnName, [Out] out String ppszName); public enum SIGDN : uint { NORMALDISPLAY = 0x00000000, PARENTRELATIVEPARSING = 0x80018001, DESKTOPABSOLUTEPARSING = 0x80028000, PARENTRELATIVEEDITING = 0x80031001, DESKTOPABSOLUTEEDITING = 0x8004c000, FILESYSPATH = 0x80058000, URL = 0x80068000, PARENTRELATIVEFORADDRESSBAR = 0x8007c001, PARENTRELATIVE = 0x80080001 } //var x = GetDriveLabel(@"C:\") public string GetDriveLabel(string driveNameAsLetterColonBackslash) { IntPtr pidl; uint dummy; string name; if (SHParseDisplayName(driveNameAsLetterColonBackslash, IntPtr.Zero, out pidl, 0, out dummy) == 0 && SHGetNameFromIDList(pidl, SIGDN.PARENTRELATIVEEDITING, out name) == 0 && name != null) { return name; } return null; }
OperatingSystem osVersionObj = Environment.OSVersion; OSVersionInfo osVersionInfo = new OSVersionInfo() { Name = GetOSName(osVersionObj), Major = osVersionObj.Version.Major, Minor = osVersionObj.Version.Minor, Build = osVersionObj.Version.Build };
Correspondance :
Operating System Version Archive du 31/05/2018 le 28/04/2020
Operating system | Version number |
---|---|
Windows 10 | 10.0* |
Windows Server 2016 | 10.0* |
Windows 8.1 | 6.3* |
Windows Server 2012 R2 | 6.3* |
Windows 8 | 6.2 |
Windows Server 2012 | 6.2 |
Windows 7 | 6.1 |
Windows Server 2008 R2 | 6.1 |
Windows Server 2008 | 6.0 |
Windows Vista | 6.0 |
Windows Server 2003 R2 | 5.2 |
Windows Server 2003 | 5.2 |
Windows XP 64-Bit Edition | 5.2 |
Windows XP | 5.1 |
Windows 2000 | 5.0 |
Single Process Instance Object Archive du 09/10/2002 le 28/04/2020
Dans Program.cs
:
[DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] private static extern bool IsIconic(IntPtr hWnd); private const int SW_RESTORE = 9; public static void RaiseOtherProcess() { Process proc = Process.GetCurrentProcess(); // Using Process.ProcessName does not function properly when // the actual name exceeds 15 characters. Using the assembly // name takes care of this quirk and is more accruate than // other work arounds. string assemblyName = Assembly.GetExecutingAssembly().GetName().Name; foreach (Process otherProc in Process.GetProcessesByName(assemblyName)) { //ignore "this" process if (proc.Id != otherProc.Id) { // Found a "same named process". // Assume it is the one we want brought to the foreground. // Use the Win32 API to bring it to the foreground. IntPtr hWnd = otherProc.MainWindowHandle; if (IsIconic(hWnd)) { ShowWindowAsync(hWnd, SW_RESTORE); } SetForegroundWindow(hWnd); break; } } } static void Main() { bool _owned; Mutex _processSync = new Mutex(true, Assembly.GetExecutingAssembly().GetName().Name + "RDVision", out _owned); if (!_owned) { RaiseOtherProcess(); return; } // La suite.