=====Trouver la bonne déclaration pour appeler les DLL Windows===== Télécharger la source du .NET depuis [[https://referencesource.microsoft.com/download.html|ReferenceSource]] et rechercher dans tous les fichiers ''UnsafeNativeMethods.cs'' ou dans le fichier ''win32native.cs''. Il y a presque tous les API Windows. ====Mauvaises pratiques==== ===IntPtr=== Ne pas utiliser ''IntPtr'' mais ''HandleRef'' pour les paramètres de type ''HWND'' selon la ''MSDN''. IntPtr iptr = ...; HandleRef href = new HandleRef(null, iptr); [[https://stackoverflow.com/questions/526661/intptr-safehandle-and-handleref-explained|IntPtr, SafeHandle and HandleRef - Explained]] {{ :lang:csharp:windows:net_-_intptr_safehandle_and_handleref_-_explained_-_stack_overflow_2020-04-28_8_23_31_am_.html |Archive du 08/02/2009 le 28/04/2020}} [[https://stackoverflow.com/questions/27348119/safehandle-and-handleref|SafeHandle and HandleRef]] {{ :lang:csharp:windows:c_-_safehandle_and_handleref_-_stack_overflow_2020-04-28_8_23_48_am_.html |Archive du 07/12/2014 le 28/04/2020}} ===LPCSTR et LPCWSTR=== 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)''. =====Récupérer le nom d'un disque dur qui est affiché depuis l'explorateur Windows et qui est différent de celui du label du disque dur===== Ne marche qu'à partir de Windows Vista. [[https://stackoverflow.com/questions/2843935/get-drive-label-in-c-sharp|Get drive label in C#]] {{ :lang:csharp:windows:get_drive_label_in_c_-_stack_overflow_2020-04-28_8_24_02_am_.html |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; } =====Version de Windows===== OperatingSystem osVersionObj = Environment.OSVersion; OSVersionInfo osVersionInfo = new OSVersionInfo() { Name = GetOSName(osVersionObj), Major = osVersionObj.Version.Major, Minor = osVersionObj.Version.Minor, Build = osVersionObj.Version.Build }; Correspondance : [[https://docs.microsoft.com/en-us/windows/win32/sysinfo/operating-system-version|Operating System Version]] {{ :lang:csharp:windows:operating_system_version_-_win32_apps_microsoft_docs_2020-04-28_8_24_00_am_.html |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| =====Accès bas niveau d'un disque dur===== [[https://code.msdn.microsoft.com/windowsapps/CCS-LABS-C-Low-Level-Disk-91676ca9|CCS LABS C#: Low Level Disk Access]] {{ :lang:csharp:windows:ccs_labs_c_23_low_level_disk_access.zip |Archive}} =====Ne lancer une application qu'une seule fois===== [[https://www.codeproject.com/Articles/3014/Single-Process-Instance-Object|Single Process Instance Object]] {{ :lang:csharp:windows:single_process_instance_object_-_codeproject_2020-04-28_8_24_00_am_.html |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.