=====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.