How can I change the master volume level? Using this code
[DllImport ("winmm.dll")]
public static extern int waveOutSetVolume (IntPtr hwo, uint dwVolume);
waveOutSetVolume (IntPtr.Zero, (((uint)uint.MaxValue & 0x0000ffff) | ((uint)uint.MaxValue << 16)));
I can set the wave volume but if the master volume is too low this won't have any effect.
Thanks for any help.
Okay, here goes:
const int MAXPNAMELEN = 32;
const int MIXER_SHORT_NAME_CHARS = 16;
const int MIXER_LONG_NAME_CHARS = 64;
[Flags] enum MIXERLINE_LINEF : uint{
ACTIVE = 0x00000001,
DISCONNECTED = 0x00008000,
SOURCE = 0x80000000
}
[Flags] enum MIXER : uint{
GETLINEINFOF_DESTINATION = 0x00000000,
GETLINEINFOF_SOURCE = 0x00000001,
GETLINEINFOF_LINEID = 0x00000002,
GETLINEINFOF_COMPONENTTYPE = 0x00000003,
GETLINEINFOF_TARGETTYPE = 0x00000004,
GETLINEINFOF_QUERYMASK = 0x0000000F,
GETLINECONTROLSF_ALL = 0x00000000,
GETLINECONTROLSF_ONEBYID = 0x00000001,
GETLINECONTROLSF_ONEBYTYPE = 0x00000002,
GETLINECONTROLSF_QUERYMASK = 0x0000000F,
GETCONTROLDETAILSF_VALUE = 0x00000000,
GETCONTROLDETAILSF_LISTTEXT = 0x00000001,
GETCONTROLDETAILSF_QUERYMASK = 0x0000000F,
OBJECTF_MIXER = 0x00000000,
OBJECTF_WAVEOUT = 0x10000000,
OBJECTF_WAVEIN = 0x20000000,
OBJECTF_MIDIOUT = 0x30000000,
OBJECTF_MIDIIN = 0x40000000,
OBJECTF_AUX = 0x50000000,
OBJECTF_HANDLE = 0x80000000,
OBJECTF_HMIXER = OBJECTF_HANDLE | OBJECTF_MIXER,
OBJECTF_HWAVEOUT = OBJECTF_HANDLE | OBJECTF_WAVEOUT,
OBJECTF_HWAVEIN = OBJECTF_HANDLE | OBJECTF_WAVEIN,
OBJECTF_HMIDIOUT = OBJECTF_HANDLE | OBJECTF_MIDIOUT,
OBJECTF_HMIDIIN = OBJECTF_HANDLE | OBJECTF_MIDIIN
}
[Flags] enum MIXERCONTROL_CT : uint{
CLASS_MASK = 0xF0000000,
CLASS_CUSTOM = 0x00000000,
CLASS_METER = 0x10000000,
CLASS_SWITCH = 0x20000000,
CLASS_NUMBER = 0x30000000,
CLASS_SLIDER = 0x40000000,
CLASS_FADER = 0x50000000,
CLASS_TIME = 0x60000000,
CLASS_LIST = 0x70000000,
SUBCLASS_MASK = 0x0F000000,
SC_SWITCH_BOOLEAN = 0x00000000,
SC_SWITCH_BUTTON = 0x01000000,
SC_METER_POLLED = 0x00000000,
SC_TIME_MICROSECS = 0x00000000,
SC_TIME_MILLISECS = 0x01000000,
SC_LIST_SINGLE = 0x00000000,
SC_LIST_MULTIPLE = 0x01000000,
UNITS_MASK = 0x00FF0000,
UNITS_CUSTOM = 0x00000000,
UNITS_BOOLEAN = 0x00010000,
UNITS_SIGNED = 0x00020000,
UNITS_UNSIGNED = 0x00030000,
UNITS_DECIBELS = 0x00040000, /* in 10ths */
UNITS_PERCENT = 0x00050000, /* in 10ths */
}
[Flags] enum MIXERCONTROL_CONTROLTYPE : uint{
CUSTOM = MIXERCONTROL_CT.CLASS_CUSTOM | MIXERCONTROL_CT.UNITS_CUSTOM,
BOOLEANMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_BOOLEAN,
SIGNEDMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_SIGNED,
PEAKMETER = SIGNEDMETER + 1,
UNSIGNEDMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_UNSIGNED,
BOOLEAN = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BOOLEAN | MIXERCONTROL_CT.UNITS_BOOLEAN,
ONOFF = BOOLEAN + 1,
MUTE = BOOLEAN + 2,
MONO = BOOLEAN + 3,
LOUDNESS = BOOLEAN + 4,
STEREOENH = BOOLEAN + 5,
BASS_BOOST = BOOLEAN + 0x00002277,
BUTTON = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BUTTON | MIXERCONTROL_CT.UNITS_BOOLEAN,
DECIBELS = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_DECIBELS,
SIGNED = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_SIGNED,
UNSIGNED = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_UNSIGNED,
PERCENT = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_PERCENT,
SLIDER = MIXERCONTROL_CT.CLASS_SLIDER | MIXERCONTROL_CT.UNITS_SIGNED,
PAN = SLIDER + 1,
QSOUNDPAN = SLIDER + 2,
FADER = MIXERCONTROL_CT.CLASS_FADER | MIXERCONTROL_CT.UNITS_UNSIGNED,
VOLUME = FADER + 1,
BASS = FADER + 2,
TREBLE = FADER + 3,
EQUALIZER = FADER + 4,
SINGLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_SINGLE | MIXERCONTROL_CT.UNITS_BOOLEAN,
MUX = SINGLESELECT + 1,
MULTIPLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_MULTIPLE | MIXERCONTROL_CT.UNITS_BOOLEAN,
MIXER = MULTIPLESELECT + 1,
MICROTIME = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MICROSECS | MIXERCONTROL_CT.UNITS_UNSIGNED,
MILLITIME = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MILLISECS | MIXERCONTROL_CT.UNITS_UNSIGNED
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct MIXERLINE{
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct TargetInfo{
public uint dwType;
public uint dwDeviceID;
public ushort wMid;
public ushort wPid;
public uint vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)]
public string szPname;
}
public uint cbStruct;
public uint dwDestination;
public uint dwSource;
public uint dwLineID;
public MIXERLINE_LINEF fdwLine;
public uint dwUser;
public uint dwComponentType;
public uint cChannels;
public uint cConnection;
public uint cControls;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_SHORT_NAME_CHARS)]
public string szShortName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_LONG_NAME_CHARS)]
public string szName;
public TargetInfo Target;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct MIXERCONTROL{
[StructLayout(LayoutKind.Explicit)]
public struct BoundsInfo{
[FieldOffset(0)]
public int lMinimum;
[FieldOffset(4)]
public int lMaximum;
[FieldOffset(0)]
public uint dwMinimum;
[FieldOffset(4)]
public uint dwMaximum;
[FieldOffset(8), MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public uint[] dwReserved;
}
[StructLayout(LayoutKind.Explicit)]
public struct MetricsInfo{
[FieldOffset(0)]
public uint cSteps;
[FieldOffset(0)]
public uint cbCustomData;
[FieldOffset(4), MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]
public uint[] dwReserved;
}
public uint cbStruct;
public uint dwControlID;
public MIXERCONTROL_CONTROLTYPE dwControlType;
public uint fdwControl;
public uint cMultipleItems;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_SHORT_NAME_CHARS)]
public string szShortName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_LONG_NAME_CHARS)]
public string szName;
public BoundsInfo Bounds;
public MetricsInfo Metrics;
}
[StructLayout(LayoutKind.Explicit)]
struct MIXERLINECONTROLS{
[FieldOffset(0)]
public uint cbStruct;
[FieldOffset(4)]
public uint dwLineID;
[FieldOffset(8)]
public uint dwControlID;
[FieldOffset(8)] // not a typo! overlaps previous field
public uint dwControlType;
[FieldOffset(12)]
public uint cControls;
[FieldOffset(16)]
public uint cbmxctrl;
[FieldOffset(20)]
public IntPtr pamxctrl;
}
[StructLayout(LayoutKind.Explicit)]
struct MIXERCONTROLDETAILS{
[FieldOffset(0)]
public uint cbStruct;
[FieldOffset(4)]
public uint dwControlID;
[FieldOffset(8)]
public uint cChannels;
[FieldOffset(12)]
public IntPtr hwndOwner;
[FieldOffset(12)] // not a typo!
public uint cMultipleItems;
[FieldOffset(16)]
public uint cbDetails;
[FieldOffset(20)]
public IntPtr paDetails;
}
[StructLayout(LayoutKind.Sequential)]
struct VOLUME{
public int left;
public int right;
}
struct MixerInfo{
public uint volumeCtl;
public uint muteCtl;
public int minVolume;
public int maxVolume;
}
[DllImport("WinMM.dll", CharSet=CharSet.Auto)]
static extern uint mixerGetLineInfo (IntPtr hmxobj, ref MIXERLINE pmxl, MIXER flags);
[DllImport("WinMM.dll", CharSet=CharSet.Auto)]
static extern uint mixerGetLineControls (IntPtr hmxobj, ref MIXERLINECONTROLS pmxlc, MIXER flags);
[DllImport("WinMM.dll", CharSet=CharSet.Auto)]
static extern uint mixerGetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags);
[DllImport("WinMM.dll", CharSet=CharSet.Auto)]
static extern uint mixerSetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags);
static MixerInfo GetMixerControls(){
MIXERLINE mxl = new MIXERLINE();
MIXERLINECONTROLS mlc = new MIXERLINECONTROLS();
mxl.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINE));
mlc.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINECONTROLS));
mixerGetLineInfo(IntPtr.Zero, ref mxl, MIXER.OBJECTF_MIXER | MIXER.GETLINEINFOF_DESTINATION);
mlc.dwLineID = mxl.dwLineID;
mlc.cControls = mxl.cControls;
mlc.cbmxctrl = (uint)Marshal.SizeOf(typeof(MIXERCONTROL));
mlc.pamxctrl = Marshal.AllocHGlobal((int)(mlc.cbmxctrl * mlc.cControls));
mixerGetLineControls(IntPtr.Zero, ref mlc, MIXER.OBJECTF_MIXER | MIXER.GETLINECONTROLSF_ALL);
MixerInfo rtn = new MixerInfo();
for(int i = 0; i < mlc.cControls; i++){
MIXERCONTROL mxc = (MIXERCONTROL)Marshal.PtrToStructure((IntPtr)((int)mlc.pamxctrl + (int)mlc.cbmxctrl * i), typeof(MIXERCONTROL));
switch(mxc.dwControlType){
case MIXERCONTROL_CONTROLTYPE.VOLUME:
rtn.volumeCtl = mxc.dwControlID;
rtn.minVolume = mxc.Bounds.lMinimum;
rtn.maxVolume = mxc.Bounds.lMaximum;
break;
case MIXERCONTROL_CONTROLTYPE.MUTE:
rtn.muteCtl = mxc.dwControlID;
break;
}
}
Marshal.FreeHGlobal(mlc.pamxctrl);
return rtn;
}
static VOLUME GetVolume(MixerInfo mi){
MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS();
mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
mcd.dwControlID = mi.volumeCtl;
mcd.cMultipleItems = 0;
mcd.cChannels = 2;
mcd.cbDetails = (uint)Marshal.SizeOf(typeof(int));
mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails);
mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER);
VOLUME rtn = (VOLUME)Marshal.PtrToStructure(mcd.paDetails, typeof(VOLUME));
Marshal.FreeHGlobal(mcd.paDetails);
return rtn;
}
static bool IsMuted(MixerInfo mi){
MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS();
mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
mcd.dwControlID = mi.muteCtl;
mcd.cMultipleItems = 0;
mcd.cChannels = 1;
mcd.cbDetails = 4;
mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails);
mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER);
int rtn = Marshal.ReadInt32(mcd.paDetails);
Marshal.FreeHGlobal(mcd.paDetails);
return rtn != 0;
}
static void AdjustVolume(MixerInfo mi, int delta){
VOLUME volume = GetVolume(mi);
if(delta > 0){
volume.left = Math.Min(mi.maxVolume, volume.left + delta);
volume.right = Math.Min(mi.maxVolume, volume.right + delta);
}else{
volume.left = Math.Max(mi.minVolume, volume.left + delta);
volume.right = Math.Max(mi.minVolume, volume.right + delta);
}
SetVolume(mi, volume);
}
static void SetVolume(MixerInfo mi, VOLUME volume){
MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS();
mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
mcd.dwControlID = mi.volumeCtl;
mcd.cMultipleItems = 0;
mcd.cChannels = 2;
mcd.cbDetails = (uint)Marshal.SizeOf(typeof(int));
mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails);
Marshal.StructureToPtr(volume, mcd.paDetails, false);
mixerSetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER);
Marshal.FreeHGlobal(mcd.paDetails);
}
static void SetMute(MixerInfo mi, bool mute){
MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS();
mcd.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
mcd.dwControlID = mi.muteCtl;
mcd.cMultipleItems = 0;
mcd.cChannels = 1;
mcd.cbDetails = 4;
mcd.paDetails = Marshal.AllocHGlobal((int)mcd.cbDetails);
Marshal.WriteInt32(mcd.paDetails, mute ? 1 : 0);
mixerSetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER);
Marshal.FreeHGlobal(mcd.paDetails);
}
This code is huge and ugly. It's a translation of some C++ code, and with having to define all the P/Invoke stuff, it's a lot more code. But I've tested it, and it works. To use it, you simply need something like:
MixerInfo mi = GetMixerControls();
AdjustVolume(mi, 100); // add 100 to the current volume
or
MixerInfo mi = GetMixerControls();
AdjustVolume(mi, (mi.maxVolume - mi.minVolume) / 10); // increase the volume by 10% of total range
or
MixerInfo mi = GetMixerControls();
SetVolume(mi, mi.maxVolume); // let's get this party crunk'd!
or
MixerInfo mi = GetMixerControls();
SetMute(mi, true); // shhhh!!!!!!
WARNING
Due to the use of fixed-sized ints and field offsets, this may fail fantastically on 64-bit Windows. I don't know, I haven't tested it and haven't paid enough attention to know if these field sizes expand to 64 bits. caveat codor
EDIT
For the sake of simplicity (relatively speaking), I've left out any error handling. You should really check the return codes of all the mixerXXX functions, but I'll leave that as an exercise for the reader (read as: I was too lazy to do this).
For the master volume (for Vista and above), that would be:
ISimpleAudioVolume::SetMasterVolume
As explained here, you may refer to the section:
Core Audio APIs in Windows Vista for more.
This call is not a Media Foundation call but a WASAPI (Windows Audio Session API) call:
ISimpleAudioVolume::SetMasterVolume (The SetMasterVolume method sets the master volume level for the audio session.)
This may be difficult however to make the UI of the Media Center reflect the new sound level set by that call, as this thread illustrates it.
For windows Xp, you can study this script and maybe this other script.
Audio Library might also be of interest.
There is also this old Audio Project which hasa master volume part:
BOOL CVolumeDlg::amdInitialize()
{
ASSERT(m_hMixer == NULL);
// get the number of mixer devices present in the system
m_nNumMixers = ::mixerGetNumDevs();
m_hMixer = NULL;
::ZeroMemory(&m_mxcaps, sizeof(MIXERCAPS));
m_strDstLineName.Empty();
m_strVolumeControlName.Empty();
m_dwMinimum = 0;
m_dwMaximum = 0;
m_dwVolumeControlID = 0;
// open the first mixer
// A "mapper" for audio mixer devices does not currently exist.
if (m_nNumMixers != 0)
{
if (::mixerOpen(&m_hMixer,
0,
reinterpret_cast<DWORD>(this->GetSafeHwnd()),
NULL,
MIXER_OBJECTF_MIXER | CALLBACK_WINDOW)
!= MMSYSERR_NOERROR)
{
return FALSE;
}
if (::mixerGetDevCaps(reinterpret_cast<UINT>(m_hMixer),
&m_mxcaps, sizeof(MIXERCAPS))
!= MMSYSERR_NOERROR)
{
return FALSE;
}
}
return TRUE;
}
BOOL CVolumeDlg::amdUninitialize()
{
BOOL bSucc = TRUE;
if (m_hMixer != NULL)
{
bSucc = (::mixerClose(m_hMixer) == MMSYSERR_NOERROR);
m_hMixer = NULL;
}
return bSucc;
}
BOOL CVolumeDlg::amdGetMasterVolumeControl()
{
if (m_hMixer == NULL)
{
return FALSE;
}
// get dwLineID
MIXERLINE mxl;
mxl.cbStruct = sizeof(MIXERLINE);
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
if (::mixerGetLineInfo(reinterpret_cast<HMIXEROBJ>(m_hMixer),
&mxl,
MIXER_OBJECTF_HMIXER |
MIXER_GETLINEINFOF_COMPONENTTYPE)
!= MMSYSERR_NOERROR)
{
return FALSE;
}
// get dwControlID
MIXERCONTROL mxc;
MIXERLINECONTROLS mxlc;
mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cControls = 1;
mxlc.cbmxctrl = sizeof(MIXERCONTROL);
mxlc.pamxctrl = &mxc;
if (::mixerGetLineControls(reinterpret_cast<HMIXEROBJ>(m_hMixer),
&mxlc,
MIXER_OBJECTF_HMIXER |
MIXER_GETLINECONTROLSF_ONEBYTYPE)
!= MMSYSERR_NOERROR)
{
return FALSE;
}
// store dwControlID
m_strDstLineName = mxl.szName;
m_strVolumeControlName = mxc.szName;
m_dwMinimum = mxc.Bounds.dwMinimum;
m_dwMaximum = mxc.Bounds.dwMaximum;
m_dwVolumeControlID = mxc.dwControlID;
return TRUE;
}
BOOL CVolumeDlg::amdGetMasterVolumeValue(DWORD &dwVal) const
{
if (m_hMixer == NULL)
{
return FALSE;
}
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
MIXERCONTROLDETAILS mxcd;
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = m_dwVolumeControlID;
mxcd.cChannels = 1;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = &mxcdVolume;
if (::mixerGetControlDetails(reinterpret_cast<HMIXEROBJ>(m_hMixer),
&mxcd,
MIXER_OBJECTF_HMIXER |
MIXER_GETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR)
{
return FALSE;
}
dwVal = mxcdVolume.dwValue;
return TRUE;
}
BOOL CVolumeDlg::amdSetMasterVolumeValue(DWORD dwVal) const
{
if (m_hMixer == NULL)
{
return FALSE;
}
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume = { dwVal };
MIXERCONTROLDETAILS mxcd;
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = m_dwVolumeControlID;
mxcd.cChannels = 1;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = &mxcdVolume;
if (::mixerSetControlDetails(reinterpret_cast<HMIXEROBJ>(m_hMixer),
&mxcd,
MIXER_OBJECTF_HMIXER |
MIXER_SETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR)
{
return FALSE;
}
return TRUE;
}
Use this free library, it's simple and does the job.
InputSimulator
It simulates a key press.
You only have to add this reference and call wherever you want static methods like these:
InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_UP);
InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_DOWN);
InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_MUTE);
Then, if you want to get the master vokume level do:
// volume update
MMDevice defaultDevice = new MMDeviceEnumerator()
.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
// veloce attesa per l'aggiornamento del volume
Thread.Sleep(100);
float level = defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar;
Doing this you'll have in level the current volume in 0-1 format (eg. 52% is 0.52) If you want to have it in 0-100 format simply do level*100
Related
Is it possible to get the real screen size in cm not in pixels ? ie i need to know the size of the sreen not its resolution.
I need this if it's possible in a windows application.
All information about screen (from manufacturer) is in registry HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY. The size of the screen is encoded, and hard to find, but it's possible.
For more information, search on the web for : EDID ("Extended display identification data") ( http://en.wikipedia.org/wiki/Extended_display_identification_data , the bytes for the size are #21 and #22)
Here the code I use to have the size (and more information, but I cleaned the code to have only the size) :
// Open the Display Reg-Key
RegistryKey displayRegistry = Registry.LocalMachine;
Boolean isFailed = false;
try
{
displayRegistry = Registry.LocalMachine.OpenSubKey(#"SYSTEM\CurrentControlSet\Enum\DISPLAY");
}
catch
{
isFailed = true;
}
if (!isFailed & (displayRegistry != null))
{
// Get all MonitorIDss
foreach (String monitorID in displayRegistry.GetSubKeyNames())
{
if (monitorID == name)
{
RegistryKey monitorIDRegistry = displayRegistry.OpenSubKey(monitorID);
if (monitorIDRegistry != null)
{
// Get all Plug&Play ID's
foreach (String subname in monitorIDRegistry.GetSubKeyNames())
{
RegistryKey pnpID = monitorIDRegistry.OpenSubKey(subname);
if (pnpID != null)
{
String[] subkeys = pnpID.GetSubKeyNames();
// Check if Monitor is active
if (subkeys.Contains("Control"))
{
if (subkeys.Contains("Device Parameters"))
{
RegistryKey devParam = pnpID.OpenSubKey("Device Parameters");
Int16 sizeH = 0;
Int16 sizeV = 0;
// Get the EDID code
byte[] edidObj = devParam.GetValue("EDID", null) as byte[];
if (edidObj != null)
{
sizeH = Convert.ToInt16(Encoding.Default.GetString(edidObj, 0x15, 1)[0]);
sizeV = Convert.ToInt16(Encoding.Default.GetString(edidObj, 0x16, 1)[0]);
}
}
}
}
}
}
}
}
}
The size is in cm (it's integer only).
You can have with this physical ratio and diagonal :
private static String GetRatio(Double MaxSizeH, Double MaxSizeV)
{
if (MaxSizeV == 0)
{
return "undefined";
}
Double ratio = MaxSizeH / MaxSizeV;
String strRatio = "4/3";
Double ecartRatio = Math.Abs(ratio - (4 / (Double)3));
if (Math.Abs(ratio - (16 / (Double)10)) < ecartRatio)
{
ecartRatio = Math.Abs(ratio - (16 / (Double)10));
strRatio = "16/10";
}
if (Math.Abs(ratio - (16 / (Double)9)) < ecartRatio)
{
ecartRatio = Math.Abs(ratio - (16 / (Double)9));
strRatio = "16/9";
}
return strRatio;
}
// diagonal in inch
private static Double GetDiagonale(Double MaxSizeH, Double MaxSizeV)
{
return 0.3937 * Math.Sqrt(MaxSizeH * MaxSizeH + MaxSizeV * MaxSizeV);
}
Edit: How to have monitor name (all connected monitors) :
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DISPLAY_DEVICE
{
[MarshalAs(UnmanagedType.U4)]
public int cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceString;
[MarshalAs(UnmanagedType.U4)]
public DisplayDeviceStateFlags StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceKey;
}
[Flags]
public enum DisplayDeviceStateFlags : int
{
/// <summary>The device is part of the desktop.</summary>
AttachedToDesktop = 0x1,
MultiDriver = 0x2,
/// <summary>The device is part of the desktop.</summary>
PrimaryDevice = 0x4,
/// <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
MirroringDriver = 0x8,
/// <summary>The device is VGA compatible.</summary>
VGACompatible = 0x10,
/// <summary>The device is removable; it cannot be the primary display.</summary>
Removable = 0x20,
/// <summary>The device has more display modes than its output devices support.</summary>
ModesPruned = 0x8000000,
Remote = 0x4000000,
Disconnect = 0x2000000
}
[DllImport("User32.dll")]
public static extern int EnumDisplayDevices(string lpDevice, int iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, int dwFlags);
private static List<NativeMethods.DISPLAY_DEVICE> GetAllDevice()
{
List<NativeMethods.DISPLAY_DEVICE> devices = new List<NativeMethods.DISPLAY_DEVICE>();
bool error = false;
for (int devId = 0; !error; devId++)
{
try
{
NativeMethods.DISPLAY_DEVICE device = new NativeMethods.DISPLAY_DEVICE();
device.cb = Marshal.SizeOf(typeof(NativeMethods.DISPLAY_DEVICE));
error = NativeMethods.EnumDisplayDevices(null, devId, ref device, 0) == 0;
if (String.IsNullOrWhiteSpace(device.DeviceID) == false)
{
devices.Add(device);
}
}
catch (Exception)
{
error = true;
}
}
return devices;
}
and to finish :
List<NativeMethods.DISPLAY_DEVICE> devices = GetAllDevice();
foreach (NativeMethods.DISPLAY_DEVICE device in devices)
{
NativeMethods.DISPLAY_DEVICE monitor = new NativeMethods.DISPLAY_DEVICE();
monitor.cb = Marshal.SizeOf(typeof(NativeMethods.DISPLAY_DEVICE));
NativeMethods.EnumDisplayDevices(device.DeviceName, 0, ref monitor, 0);
String monitorname = monitor.DeviceID.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Skip(1).FirstOrDefault();
GetMonitorDetail(monitorname);
}
i found this
public class NativeMethods
{
[DllImport("gdi32.dll", EntryPoint = "CreateDC", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CreateDC(string lpszDriver, string lpszDeviceName, string lpszOutput, IntPtr devMode);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll", SetLastError = true)]
private static extern Int32 GetDeviceCaps(IntPtr hdc, Int32 capindex);
private const int LOGPIXELSX = 88;
private static int _dpi = -1;
public static int DPI
{
get
{
if (_dpi != -1)
return _dpi;
_dpi = 96;
try
{
IntPtr hdc = CreateDC("DISPLAY", null, null, IntPtr.Zero);
if (hdc != IntPtr.Zero)
{
_dpi = GetDeviceCaps(hdc, LOGPIXELSX);
if (_dpi == 0)
_dpi = 96;
DeleteDC(hdc);
}
}
catch (Exception)
{
}
return _dpi;
}
}
}
that uses PInvoke to get the DPI in other question about the subject and i post it here because i only saw links.
i will mention this is not a common thing and i don't know why you will need that. this sounds like an A-B problem, so i'll say you need to be absolutly sure you need the DPI before using that
look at Lasse V. Karlsen comment please. this might not be accurate, so take that with care
I want to collect all list of machines in local network, for that I am trying below code. But it always return me current machine name only. How Can I get all machines ip/name in local network?.
I have tried all SV_101_TYPES, among these some returns empty list and remaining returns only current machine name.
Could anyone guide me, what is wrong?
public class Program
{
static void Main(string[] args)
{
ArrayList machines = NetApi32.GetServerList(NetApi32.SV_101_TYPES.SV_TYPE_ALL);
}
}
/// <summary>
/// Summary description for Class1.
/// </summary>
///
public class NetApi32
{
// constants
public const uint ERROR_SUCCESS = 0;
public const uint ERROR_MORE_DATA = 234;
public enum SV_101_TYPES : uint
{
SV_TYPE_WORKSTATION = 0x00000001,
SV_TYPE_SERVER = 0x00000002,
SV_TYPE_SQLSERVER = 0x00000004,
SV_TYPE_DOMAIN_CTRL = 0x00000008,
SV_TYPE_DOMAIN_BAKCTRL = 0x00000010,
SV_TYPE_TIME_SOURCE = 0x00000020,
SV_TYPE_AFP = 0x00000040,
SV_TYPE_NOVELL = 0x00000080,
SV_TYPE_DOMAIN_MEMBER = 0x00000100,
SV_TYPE_PRINTQ_SERVER = 0x00000200,
SV_TYPE_DIALIN_SERVER = 0x00000400,
SV_TYPE_XENIX_SERVER = 0x00000800,
SV_TYPE_SERVER_UNIX = 0x00000800,
SV_TYPE_NT = 0x00001000,
SV_TYPE_WFW = 0x00002000,
SV_TYPE_SERVER_MFPN = 0x00004000,
SV_TYPE_SERVER_NT = 0x00008000,
SV_TYPE_POTENTIAL_BROWSER = 0x00010000,
SV_TYPE_BACKUP_BROWSER = 0x00020000,
SV_TYPE_MASTER_BROWSER = 0x00040000,
SV_TYPE_DOMAIN_MASTER = 0x00080000,
SV_TYPE_SERVER_OSF = 0x00100000,
SV_TYPE_SERVER_VMS = 0x00200000,
SV_TYPE_WINDOWS = 0x00400000,
SV_TYPE_DFS = 0x00800000,
SV_TYPE_CLUSTER_NT = 0x01000000,
SV_TYPE_TERMINALSERVER = 0x02000000,
SV_TYPE_CLUSTER_VS_NT = 0x04000000,
SV_TYPE_DCE = 0x10000000,
SV_TYPE_ALTERNATE_XPORT = 0x20000000,
SV_TYPE_LOCAL_LIST_ONLY = 0x40000000,
SV_TYPE_DOMAIN_ENUM = 0x80000000,
SV_TYPE_ALL = 0xFFFFFFFF
};
[StructLayout(LayoutKind.Sequential)]
public struct SERVER_INFO_101
{
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
public UInt32 sv101_platform_id;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string sv101_name;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
public UInt32 sv101_version_major;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
public UInt32 sv101_version_minor;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
public UInt32 sv101_type;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string sv101_comment;
};
public enum PLATFORM_ID
{
PLATFORM_ID_DOS = 300,
PLATFORM_ID_OS2 = 400,
PLATFORM_ID_NT = 500,
PLATFORM_ID_OSF = 600,
PLATFORM_ID_VMS = 700
}
[DllImport("netapi32.dll", EntryPoint = "NetServerEnum")]
public static extern int NetServerEnum([MarshalAs(UnmanagedType.LPWStr)]string servername,
int level,
out IntPtr bufptr,
int prefmaxlen,
ref int entriesread,
ref int totalentries,
SV_101_TYPES servertype,
[MarshalAs(UnmanagedType.LPWStr)]string domain,
IntPtr resume_handle);
[DllImport("netapi32.dll", EntryPoint = "NetApiBufferFree")]
public static extern int
NetApiBufferFree(IntPtr buffer);
[DllImport("Netapi32", CharSet = CharSet.Unicode)]
private static extern int NetMessageBufferSend(
string servername,
string msgname,
string fromname,
string buf,
int buflen);
public static int NetMessageSend(string serverName, string messageName, string fromName, string strMsgBuffer, int iMsgBufferLen)
{
return NetMessageBufferSend(serverName, messageName, fromName, strMsgBuffer, iMsgBufferLen * 2);
}
public static ArrayList GetServerList(NetApi32.SV_101_TYPES ServerType)
{
int entriesread = 0, totalentries = 0;
ArrayList alServers = new ArrayList();
do
{
// Buffer to store the available servers
// Filled by the NetServerEnum function
IntPtr buf = new IntPtr();
SERVER_INFO_101 server;
int ret = NetServerEnum(null, 101, out buf, -1, ref entriesread, ref totalentries, ServerType, null, IntPtr.Zero);
// if the function returned any data, fill the tree view
if (ret == ERROR_SUCCESS ||
ret == ERROR_MORE_DATA ||
entriesread > 0)
{
IntPtr ptr = buf;
for (int i = 0; i < entriesread; i++)
{
// cast pointer to a SERVER_INFO_101 structure
server = (SERVER_INFO_101)Marshal.PtrToStructure(ptr, typeof(SERVER_INFO_101));
//Cast the pointer to a ulong so this addition will work on 32-bit or 64-bit systems.
ptr = (IntPtr)((ulong)ptr + (ulong)Marshal.SizeOf(server));
// add the machine name and comment to the arrayList.
//You could return the entire structure here if desired
alServers.Add(server);
}
}
// free the buffer
NetApiBufferFree(buf);
}
while
(
entriesread < totalentries &&
entriesread != 0
);
return alServers;
}
}
Question:
In C/C++/C#. (I need it for C#, but C and C++ is also fine).
How can I do a mount -a on Linux.
I mean programmatically, without starting a process like
system("mount -a");
Edit:
Note the "-a".
My question is not actually about how to mount A mountpoint.
It's about how to mount ALL mountpoints in /etc/fstab.
That means parsing the file, extracting the mountpoints, check if already mounted, and only if not already mounted, mount...
Check out the man page by typing man 2 mount. It talks about a system call that can avoid the actual use of system():
#include <sys/mount.h>
int mount(const char *source, const char *target, const char *filesystemtype,
unsigned long mountflags, const void *data);
#Ignacio Vazquez-Abrams:
About your "no way to perform this in C#" ...
Proof that you're wrong by contradiction:
The bellow code is capable of doing the same as
(apt-get install jfsutils)
dd if=/dev/zero of=jfs.dsk bs=1048576 count=150
mkfs.jfs -O jfs.dsk
mkdir -p /mnt/jfs
mount /volumes/jfs.dsk /mnt/jfs -t jfs -o loop
umount /mnt/jfs/
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Syscalls
{
public class Linux
{
// apt-get source util-linux
// ./mount/loop.h
// ./mount/mount.c
// ./mount/lomount.c
// ./include/linux_version.h
// ./lib/linux_version.c
// ./include/linux_reboot.h
protected const int LOOP_SET_FD = 0x4C00;
protected const int LOOP_CLR_FD = 0x4C01;
protected const int LOOP_GET_STATUS = 0x4C03;
protected const int LOOP_SET_STATUS = 0x4C02;
protected const int LOOP_GET_STATUS64 = 0x4C05;
protected const int LOOP_SET_STATUS64 = 0x4C04;
protected const int LO_NAME_SIZE = 64;
protected const int LO_KEY_SIZE = 32;
protected const int PATH_MAX = 4096;
// MS_RELATIME //(default for Linux >= 2.6.30)
// MS_STRICTATIME //(default for Linux < 2.6.30)
// http://harmattan-dev.nokia.com/docs/library/html/manpages/headers/sys/mount.html
public enum MountFlags : ulong
{
MS_RDONLY = 1, // Mount read-only.
MS_NOSUID = 2, // Ignore suid and sgid bits.
MS_NODEV = 4, // Disallow access to device special files.
MS_NOEXEC = 8, // Disallow program execution.
MS_SYNCHRONOUS = 16, // Writes are synced at once.
MS_REMOUNT = 32, // Alter flags of a mounted FS.
MS_MANDLOCK = 64, // Allow mandatory locks on an FS.
S_WRITE = 128, // Write on file/directory/symlink.
S_APPEND = 256, // Append-only file.
S_IMMUTABLE = 512, // Immutable file.
MS_NOATIME = 1024, // Do not update access times.
MS_NODIRATIME = 2048, // Do not update directory access times.
MS_BIND = 4096, // Bind directory at different place.
}; // End Enum MountFlags : ulong
/*
// http://unix.superglobalmegacorp.com/Net2/newsrc/sys/fcntl.h.html
[Flags]
protected enum OpenFlags : int
{
// open-only flags
O_RDONLY = 0x0000, // open for reading only
O_WRONLY = 0x0001, // open for writing only
O_RDWR = 0x0002, // open for reading and writing
O_ACCMODE = 0x0003, // mask for above modes
//#ifdef KERNEL
FREAD = 0x0001,
FWRITE = 0x0002,
//#endif
O_NONBLOCK = 0x0004, // no delay
O_APPEND = 0x0008, // set append mode
//#ifndef _POSIX_SOURCE
O_SHLOCK = 0x0010, // open with shared file lock
O_EXLOCK = 0x0020, // open with exclusive file lock
O_ASYNC = 0x0040, // signal pgrp when data ready
O_FSYNC = 0x0080, // synchronous writes
//#endif
O_CREAT = 0x0200, // create if nonexistant
O_TRUNC = 0x0400, // truncate to zero length
O_EXCL = 0x0800, // error if already exists
//#ifdef KERNEL
FMARK = 0x1000, // mark during gc()
FDEFER = 0x2000, // defer for next gc pass
FHASLOCK = 0x4000 // descriptor holds advisory lock
} // End Enum OpenFlags : int
*/
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
protected struct loop_info
{
public int lo_number;
public System.UIntPtr lo_device; //my_dev_t lo_device; // my_dev_t: long unsigned int
public System.UIntPtr lo_inode; //unsigned long lo_inode;
public System.UIntPtr lo_rdevice; //my_dev_t lo_rdevice;// my_dev_t: long unsigned int
public int lo_offset;
public int lo_encrypt_type;
public int lo_encrypt_key_size;
public int lo_flags;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = LO_NAME_SIZE)]
public string lo_name; //char lo_name[LO_NAME_SIZE];
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = LO_KEY_SIZE)]
public string lo_encrypt_key; //unsigned char lo_encrypt_key[LO_KEY_SIZE];
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 2)]
public System.UIntPtr[] lo_init; //unsigned long lo_init[2];
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 4)]
public string reserved; //char reserved[4];
}; // End Struct loop_info
protected struct loop_info64
{
public System.UInt64 lo_device;
public System.UInt64 lo_inode;
public System.UInt64 lo_rdevice;
public System.UInt64 lo_offset;
public System.UInt64 lo_sizelimit; /* bytes, 0 == max available */
public System.UInt32 lo_number;
public System.UInt32 lo_encrypt_type;
public System.UInt32 lo_encrypt_key_size;
public System.UInt32 lo_flags;
// http://stackoverflow.com/questions/1725855/uint8-t-vs-unsigned-char
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = LO_NAME_SIZE)]
public string lo_file_name; // uint8_t lo_file_name[LO_NAME_SIZE];
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = LO_NAME_SIZE)]
public string lo_crypt_name; // uint8_t lo_crypt_name[LO_NAME_SIZE];
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = LO_KEY_SIZE)]
public string lo_encrypt_key; // uint8_t lo_encrypt_key[LO_KEY_SIZE];
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 2)]
public System.UInt64[] lo_init;
}; // End Struct loop_info64
// http://www.student.cs.uwaterloo.ca/~cs350/common/os161-src-html/kern_2include_2kern_2stat_8h.html
protected static bool S_ISBLK(int mode)
{
const uint S_IFMT = 070000;
const uint S_IFBLK = 050000;
return (((mode) & S_IFMT) == S_IFBLK);
} // End Function S_ISBLK
public static int KERNEL_VERSION()
{
Mono.Unix.Native.Utsname unameres = new Mono.Unix.Native.Utsname();
Mono.Unix.Native.Syscall.uname(out unameres);
System.Text.RegularExpressions.Match ma = System.Text.RegularExpressions.Regex.Match(unameres.release, #"(\d+).(\d+).(\d+)(-)?(\d+)?");
string strMajor = ma.Groups[1].Value;
string strMinor = ma.Groups[2].Value;
string strTiny = ma.Groups[3].Value;
string strPatchlevel = ma.Groups[5].Value;
int a = System.Convert.ToInt32(strMajor);
int b = System.Convert.ToInt32(strMinor);
int c = System.Convert.ToInt32(strTiny);
return KERNEL_VERSION(a, b, c);
} // End Function KERNEL_VERSION
//# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
public static int KERNEL_VERSION(int a, int b, int c)
{
return (((a) << 16) + ((b) << 8) + (c));
}
public static string CreateVirtualDisk(int iSize)
{
string strBaseDirectory = #"/volumes/";
string strFileName = System.Guid.NewGuid().ToString().Replace("-", "") + ".dsk";
string strFileNameAndPath = System.IO.Path.Combine(strBaseDirectory, strFileName);
using (var fs = new System.IO.FileStream(strFileNameAndPath, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
{
fs.SetLength(iSize);
} // End Using fs
return strFileNameAndPath;
} // End Function CreateVirtualDisk
// umount("/mnt/testdisk");
public static bool umount(string strMountPoint)
{
int status = UnsafeNativeMethods.umount(strMountPoint);
if (status == 0)
Console.WriteLine("Successfully unmounted device.");
else
Console.WriteLine("Unmount status: " + status.ToString());
if (status == 0)
return true;
return false;
} // End Function Unmount
public static string find_unused_loop_device()
{
string dev;
int fd;
Mono.Unix.Native.Stat statbuf;
loop_info loopinfo = new loop_info();
loop_info64 lo64 = new loop_info64();
for (int i = 0; i <= 7; i++)
{
dev = "/dev/loop" + i.ToString();
if (System.Convert.ToBoolean(Mono.Unix.Native.Syscall.stat(dev, out statbuf)) == (false && S_ISBLK((int)statbuf.st_mode)))
{
if ((fd = Mono.Unix.Native.Syscall.open(dev, Mono.Unix.Native.OpenFlags.O_RDONLY)) >= 0)
{
// This block was commented out initially
if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS64, ref lo64) == 0)
{
if (Mono.Unix.Native.Syscall.GetLastError() == Mono.Unix.Native.Errno.ENXIO)
{ // probably free
Mono.Unix.Native.Syscall.close(fd);
return dev;
}
}
if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS, ref loopinfo) != 0)
{
// http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/include/asm-generic/errno-base.h#L9
// ENXIO - No such device or address
// The device accessed by a command is physically not present,
// or the address of the device is not present
if (Mono.Unix.Native.Syscall.GetLastError() == Mono.Unix.Native.Errno.ENXIO)
{
// that means the device is most-likely free
Mono.Unix.Native.Syscall.close(fd);
return dev;
}
} // End if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS, ref loopinfo) != 0)
Mono.Unix.Native.Syscall.close(fd);
} // End if ((fd = UnsafeNativeMethods.open(dev, OpenFlags.O_RDONLY)) >= 0)
} // End if (System.Convert.ToBoolean(Mono.Unix.Native.Syscall.stat(dev, out statbuf)) == (false && S_ISBLK((int)statbuf.st_mode)))
} // Next i
return null;
} // End Function find_unused_loop_device
public static int set_loop(string device, string file, int offset, ref int loopro)
{
loop_info loopinfo = new loop_info();
int fd = 0, ffd = 0;
Mono.Unix.Native.OpenFlags mode;
mode = loopro != 0 ? Mono.Unix.Native.OpenFlags.O_RDONLY : Mono.Unix.Native.OpenFlags.O_RDWR;
if (
(
ffd = Mono.Unix.Native.Syscall.open(file, mode)
) < 0
&&
(
(!System.Convert.ToBoolean((int)loopro))
&&
(
Mono.Unix.Native.Syscall.GetLastError() != Mono.Unix.Native.Errno.EROFS
||
(ffd = Mono.Unix.Native.Syscall.open(file, mode = Mono.Unix.Native.OpenFlags.O_RDONLY))
< 0
)
)
) // if
{
Console.WriteLine("Error: file: " + file);
//perror_msg("%s", file);
return 1;
} // End if
if ((fd = Mono.Unix.Native.Syscall.open(device, mode)) < 0)
{
Mono.Unix.Native.Syscall.close(ffd);
Console.WriteLine("Error: device: " + device);
//perror_msg("%s", device);
return 1;
}
loopro = System.Convert.ToInt32(mode == Mono.Unix.Native.OpenFlags.O_RDONLY);
//memset(&loopinfo, 0, sizeof(loopinfo));
//safe_strncpy(loopinfo.lo_name, file, LO_NAME_SIZE);
//strncpy(loopinfo.lo_name, file, LO_NAME_SIZE);
loopinfo.lo_name = string.IsNullOrEmpty(file) ? null : file.Substring(0, Math.Min(file.Length, LO_NAME_SIZE));
loopinfo.lo_offset = offset;
loopinfo.lo_encrypt_key_size = 0;
if (UnsafeNativeMethods.ioctl(fd, LOOP_SET_FD, ffd) < 0)
{
Console.WriteLine("ioctl: LOOP_SET_FD");
//perror_msg("ioctl: LOOP_SET_FD");
Mono.Unix.Native.Syscall.close(fd);
Mono.Unix.Native.Syscall.close(ffd);
return 1;
}
if (UnsafeNativeMethods.ioctl(fd, LOOP_SET_STATUS, ref loopinfo) < 0)
{
int ro = 0;
UnsafeNativeMethods.ioctl(fd, LOOP_CLR_FD, ref ro);
//perror_msg("ioctl: LOOP_SET_STATUS");
Console.WriteLine("ioctl: LOOP_SET_STATUS");
Mono.Unix.Native.Syscall.close(fd);
Mono.Unix.Native.Syscall.close(ffd);
return 1;
}
Mono.Unix.Native.Syscall.close(fd);
Mono.Unix.Native.Syscall.close(ffd);
return 0;
} // End Function set_loop
public static int del_loop(string device)
{
int fd;
if ((fd = Mono.Unix.Native.Syscall.open(device, Mono.Unix.Native.OpenFlags.O_RDONLY)) < 0)
{
//perror_msg("%s", device);
Console.WriteLine("Error description: " + Mono.Unix.Native.Syscall.strerror(Mono.Unix.Native.Syscall.GetLastError()));
return 0;
}
int r = 0;
if (UnsafeNativeMethods.ioctl(fd, LOOP_CLR_FD, ref r) < 0)
{
//perror_msg("ioctl: LOOP_CLR_FD");
Console.WriteLine("ioctl: LOOP_CLR_FD\nError description: " + Mono.Unix.Native.Syscall.strerror(Mono.Unix.Native.Syscall.GetLastError()));
return 0;
}
Mono.Unix.Native.Syscall.close(fd);
Console.WriteLine("Successfully closed loop-device\n");
return 1;
} // End Function del_loop
public static bool mount(string strDevice, string strMountPoint, string strFsType)
{
return mount(strDevice, strMountPoint, strFsType, MountFlags.MS_NOATIME);
}
public static bool mount(string strDevice, string strMountPoint, string strFsType, MountFlags mflags)
{
return mount(strDevice, strMountPoint, strFsType, mflags, IntPtr.Zero);
}
// http://cboard.cprogramming.com/c-programming/126630-using-sys-mount-h-mounting-usb-thumb-drive.html
// http://stackoverflow.com/questions/10458549/mount-usb-drive-in-linux-with-c
// mount("/dev/loop1", "/mnt/testdisk", "vfat");
public static bool mount(string strDevice, string strMountPoint, string strFsType, MountFlags mflags, IntPtr options)
{
// http://linux.die.net/man/2/mount
// MS_RDONLY
// MS_RELATIME (default for Linux >= 2.6.30)
// MS_STRICTATIME (default for Linux < 2.6.30)
if (UnsafeNativeMethods.mount(strDevice, strMountPoint, strFsType, mflags, options) != 0)
{
Mono.Unix.Native.Errno errno = Mono.Unix.Native.Syscall.GetLastError();
if (errno == Mono.Unix.Native.Errno.EBUSY)
{
Console.WriteLine("Mountpoint busy");
}
else
{
Console.WriteLine("Mount error: " + Mono.Unix.Native.Syscall.strerror(errno));
}
return false;
}
else
{
Console.WriteLine("Successfully mounted device !");
}
return true; ;
} // End Function mount
static class UnsafeNativeMethods
{
//string name = "Test";
//TypedReference tf = __makeref(name);
//int c = VarSum(2, __arglist(__makeref(name)));
// http://khason.net/blog/how-to-pinvoke-varargs-variable-arguments-in-c-or-hidden-junk-in-clr/
// //int rv = ioctl(2, 3, __arglist(5, 10));
[System.Runtime.InteropServices.DllImportAttribute("libc", EntryPoint = "ioctl",
CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
public static extern int ioctl(int descriptor, int request, __arglist);
[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
public static extern int ioctl(int d, int request, int data);
[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
public static extern int ioctl(int d, int request, ref int data);
[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
public static extern int ioctl(int d, int request, ref loop_info data);
[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
public static extern int ioctl(int d, int request, ref loop_info64 data);
//[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
//public static extern int open([System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]string pathname, OpenFlags flags);
//[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
//public static extern int close(int fd);
//[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
//public static extern IntPtr read(int fd, IntPtr buffer, UIntPtr count);
///////unsafe public static extern IntPtr read(int fd, void* buffer, UIntPtr count);
// http://linux.die.net/man/2/mount
// http://www.kernel.org/doc/man-pages/online/pages/man2/mount.2.html
[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
private static extern int mount(string source, string target, string filesystemtype, UIntPtr mountflags, System.IntPtr data);
//int mount(const char *source, const char *target, const char *filesystemtype, ulong mountflags, const void *data);
public static int mount(string source, string target, string filesystemtype, MountFlags mountflags, System.IntPtr data)
{
System.UIntPtr p = new System.UIntPtr((ulong)mountflags);
return mount(source, target, filesystemtype, p, data);
} // End Function mount
[System.Runtime.InteropServices.DllImport("libc", SetLastError = true)]
public static extern int umount(string strMountPoint);
// extern int umount (__const char *__special_file);
} // End Class UnsafeNativeMethods
public static void TryMount()
{
const bool SUCCESS = true;
// int iReturnCode = Mono.Unix.Native.Syscall.system("mount -a");
// int iReturnCode = Mono.Unix.Native.Syscall.system("mount /volumes/jfs.dsk /mnt/jfs -t jfs -o loop");
// int iReturnCode = Mono.Unix.Native.Syscall.system("mkfs.jfs -O \"jfs.dsk\"");
string strLoopDeviceToUse = find_unused_loop_device();
string strMountPoint = "/mnt/testdisk";
int ro = 0;
set_loop(strLoopDeviceToUse, "/volumes/testdisk.dsk", 0, ref ro);
string strLoopDeviceToUse2 = find_unused_loop_device();
bool status = false;
int mountAttempts = 0;
do
{
//status = mount("/dev/sda1", "/media/usb0", "vfat", MS_MGC_VAL | MS_NOSUID, "");
status = mount(strLoopDeviceToUse, strMountPoint, "vfat", MountFlags.MS_NOATIME);
if (status != SUCCESS)
System.Threading.Thread.Sleep(1000);
mountAttempts++;
} while (status != SUCCESS && mountAttempts < 3);
} // End Sub TryMount
// In gcc or g++, to show all of the macros that are defined for a given platform:
// gcc -dM -E test.c
// or
// g++ -dM -E test.cpp
// http://manual.cream.org/index.cgi/gnu_dev_major.3
// http://www.gnu.org/software/gnulib/coverage/usr/include/sys/sysmacros.h.gcov.frameset.html
// http://en.wikipedia.org/wiki/C_data_types
protected static uint gnu_dev_major(System.UInt64 __dev)
{
return (uint)((uint)(((__dev >> 8) & 0xfff)) | ((uint)(__dev >> 32) & ~0xfff));
}
protected static uint gnu_dev_minor(System.UInt64 __dev)
{
return (uint)((uint)(__dev & 0xff) | ((uint)(__dev >> 12) & ~0xff));
}
public static string loopfile_from_sysfs(string device)
{
string res = null;
Mono.Unix.Native.Stat st;
System.IntPtr f;
//if (stat(device, &st) || !S_ISBLK(st.st_mode))
//if (System.Convert.ToBoolean(Mono.Unix.Native.Syscall.stat(device, out st)) || !S_ISBLK((int) st.st_mode))
// return null;
Mono.Unix.Native.Syscall.stat(device, out st);
const string _PATH_SYS_DEVBLOCK = "/sys/dev/block";
string strPath = string.Format("{0}/{1}:{2}/loop/backing_file", _PATH_SYS_DEVBLOCK, gnu_dev_major(st.st_rdev), gnu_dev_minor(st.st_rdev));
f = Mono.Unix.Native.Syscall.fopen(strPath, "r");
if (f == IntPtr.Zero)
return null;
Mono.Unix.Native.Syscall.fclose(f);
res = System.IO.File.ReadAllText(strPath);
strPath = null;
return res;
} // End Function loopfile_from_sysfs
public static string loopdev_get_loopfile(string device)
{
string res = loopfile_from_sysfs(device);
if (res == null)
{
loop_info lo = new loop_info();
loop_info64 lo64 = new loop_info64();
int fd;
if ((fd = Mono.Unix.Native.Syscall.open(device, Mono.Unix.Native.OpenFlags.O_RDONLY)) < 0)
return null;
if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS64, ref lo64) == 0)
{
//lo64.lo_file_name[LO_NAME_SIZE-2] = '*';
//lo64.lo_file_name[LO_NAME_SIZE-1] = 0;
//res = strdup((char *) lo64.lo_file_name);
res = lo64.lo_file_name;
Console.WriteLine("LOOP_GET_STATUS64");
}
else if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS, ref lo) == 0)
{
//lo.lo_name[LO_NAME_SIZE-2] = '*';
//lo.lo_name[LO_NAME_SIZE-1] = 0;
//res = strdup((char *) lo.lo_name);
res = lo.lo_name;
Console.WriteLine("LOOP_GET_STATUS");
}
Mono.Unix.Native.Syscall.close(fd);
} // End if (res == null)
return res;
} // End Function loopdev_get_loopfile
public static void TryUnmount()
{
/*
string strMountPoint = "/mnt/testdisk";
umount(strMountPoint);
System.Threading.Thread.Sleep(1000);
del_loop("/dev/loop2");
*/
string xxx = loopdev_get_loopfile("/dev/loop0");
Console.WriteLine("xxx: " + xxx);
}
// kernel-support:
// grep hfs /proc/filesystems
// cat /proc/partitions
// apt-get install hfsprogs
// sudo modprobe hfsplus
// dd if=/dev/zero of=hfsplus.dsk bs=1048576 count=150
// mkfs.hfsplus /volumes/hfsplus.dsk
// mkfs.hfsplus hfsplus.dsk
// apt-get install jfsutils
// dd if=/dev/zero of=jfs.dsk bs=1048576 count=150
// mkfs.jfs -O jfs.dsk
// mkdir -p /mnt/jfs
// mount /volumes/jfs.dsk /mnt/jfs -t jfs -o loop
// umount /mnt/jfs/
// mkdir -p /mnt/hfsplus
// mount -t hfsplus /volumes/hfsplus.dsk /mnt/hfsplus/ -o loop
//
} // End Class Linux
} // End Namespace Syscalls
// http://ubuntuforums.org/showthread.php?t=135113
// http://stackoverflow.com/questions/7027151/call-expect-script-in-c-process
// http://linux.die.net/man/1/expect
// http://linux.die.net/man/3/libexpect
// http://linuxcommand.org/man_pages/losetup8.html
// losetup /dev/loop0 /file
// losetup -d /dev/loop0
// http://linux.about.com/library/cmd/blcmdl8_losetup.htm
To perma-mount it in fstab, you need to get the partition uuid (blkid)
getmntent can help you read /etc/fstab (and then use the mount function in the other answers).
I want to get the hardwired serial number from the hard disk but NOT using WMI. I tried using WMI code, and it doesn't work on my machine for sure. So is there any alternative in .NET for finding the Serial Number of a physical hard disk?
This should help get started:
How to get Physical HDD serial number without WMI
Regarding your problem with WMI not returning data; Are you sure how to the right privileges to get data from WMI? You can use WMI Tools to check/fix this.
Use the createfile as shown below. It may require administrative permissions.Add 4 text boxes and a button in your code.
private const int CREATE_NEW = 1;
private const int OPEN_EXISTING = 3;
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
// 10000000000000000000000000000000 --- GENERIC_READ
// 01000000000000000000000000000000 --- GENERIC_WRITE
// 00100000000000000000000000000000 --- GENERIC_EXECUTE
// 00010000000000000000000000000000 --- GENERIC_ALL
//Securable objects use an access mask format in which the
//four high-order bits specify generic access rights
private const int FILE_SHARE_READ = 0x1;
private const int FILE_SHARE_WRITE = 0x2;
// 00000000000000000000000000000001 --- FILE_SHARE_READ
// 00000000000000000000000000000010 --- FILE_SHARE_WRITE
// 00000000000000000000000000000100 --- FILE_SHARE_DELETE
private const int VER_PLATFORM_WIN32_NT = 2;
private const int DFP_RECEIVE_DRIVE_DATA = 0x7C088;
// 0 000000000000111 11 0 00000100010 00
// Common Device Type Required Access Custom Function Code Transfer Type
private const int INVALID_HANDLE_VALUE = -1;
public enum DriveTypes { Fixed, Removable, Unknown };
public string[] DriveStrings = { "Fixed", "Removable", "Unknown" };
[StructLayout(LayoutKind.Sequential, Size = 8)]
private class IDEREGS
{
public byte Features;
public byte SectorCount;
public byte SectorNumber;
public byte CylinderLow;
public byte CylinderHigh;
public byte DriveHead;
public byte Command;
public byte Reserved;
}
[StructLayout(LayoutKind.Sequential, Size = 32)]
private class SENDCMDINPARAMS
{
public int BufferSize;
public IDEREGS DriveRegs;
public byte DriveNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public int[] Reserved2;
public SENDCMDINPARAMS()
{
DriveRegs = new IDEREGS();
Reserved = new byte[3];
Reserved2 = new int[4];
}
}
[StructLayout(LayoutKind.Sequential, Size = 12)]
private class DRIVERSTATUS
{
public byte DriveError;
public byte IDEStatus;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public int[] Reserved2;
public DRIVERSTATUS()
{
Reserved = new byte[2];
Reserved2 = new int[2];
}
}
[StructLayout(LayoutKind.Sequential)]
private class IDSECTOR
{
public short GenConfig;
public short NumberCylinders;
public short Reserved;
public short NumberHeads;
public short BytesPerTrack;
public short BytesPerSector;
public short SectorsPerTrack;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public short[] VendorUnique;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] SerialNumber;
public short BufferClass;
public short BufferSize;
public short ECCSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] FirmwareRevision;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public char[] ModelNumber;
public short MoreVendorUnique;
public short DoubleWordIO;
public short Capabilities;
public short Reserved1;
public short PIOTiming;
public short DMATiming;
public short BS;
public short NumberCurrentCyls;
public short NumberCurrentHeads;
public short NumberCurrentSectorsPerTrack;
public int CurrentSectorCapacity;
public short MultipleSectorCapacity;
public short MultipleSectorStuff;
public int TotalAddressableSectors;
public short SingleWordDMA;
public short MultiWordDMA;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 382)]
public byte[] Reserved2;
public IDSECTOR()
{
VendorUnique = new short[3];
Reserved2 = new byte[382];
FirmwareRevision = new char[8];
SerialNumber = new char[20];
ModelNumber = new char[40];
}
}
[StructLayout(LayoutKind.Sequential)]
private class SENDCMDOUTPARAMS
{
public int BufferSize;
public DRIVERSTATUS Status;
public IDSECTOR IDS;
public SENDCMDOUTPARAMS()
{
Status = new DRIVERSTATUS();
IDS = new IDSECTOR();
}
}
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern int CloseHandle(int hObject);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern int CreateFile(
string lpFileName,
uint dwDesiredAccess,
int dwShareMode,
int lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
int hTemplateFile
);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern int DeviceIoControl(
int hDevice,
int dwIoControlCode,
[In(), Out()] SENDCMDINPARAMS lpInBuffer,
int lpInBufferSize,
[In(), Out()] SENDCMDOUTPARAMS lpOutBuffer,
int lpOutBufferSize,
ref int lpBytesReturned,
int lpOverlapped
);
private string SwapChars(char[] chars)
{
for (int i = 0; i <= chars.Length - 2; i += 2)
{
char t;
t = chars[i];
chars[i] = chars[i + 1];
chars[i + 1] = t;
}
string s = new string(chars);
return s;
}
private void button1_Click(object sender, System.EventArgs e)
{
string serialNumber = " ", model = " ", firmware = " ";
bool result;
DriveTypes driveType = DriveTypes.Unknown;
int handle, returnSize = 0;
int driveNumber = 0;
SENDCMDINPARAMS sci = new SENDCMDINPARAMS();
SENDCMDOUTPARAMS sco = new SENDCMDOUTPARAMS();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
// \\.\PhysicalDrive0 Opens the first physical drive.
// \\.\PhysicalDrive2 Opens the third physical drive.
// see more info on http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
handle = CreateFile("\\\\.\\PhysicalDrive" + "0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
else // for win'9x
handle = CreateFile("\\\\.\\Smartvsd", 0, 0, 0, CREATE_NEW, 0, 0);
if (handle != INVALID_HANDLE_VALUE)
{
sci.DriveNumber = (byte)driveNumber;
sci.BufferSize = Marshal.SizeOf(sco);
sci.DriveRegs.DriveHead = (byte)(0xA0 | driveNumber << 4);
sci.DriveRegs.Command = 0xEC;
sci.DriveRegs.SectorCount = 1;
sci.DriveRegs.SectorNumber = 1;
if (DeviceIoControl(handle, DFP_RECEIVE_DRIVE_DATA, sci, Marshal.SizeOf(sci), sco, Marshal.SizeOf(sco), ref returnSize, 0) != 0)
{
serialNumber = SwapChars(sco.IDS.SerialNumber);
model = SwapChars(sco.IDS.ModelNumber);
firmware = SwapChars(sco.IDS.FirmwareRevision);
}
textBox1.Text = serialNumber;
textBox2.Text = model;
textBox3.Text = firmware;
if ((sco.IDS.GenConfig & 0x80) == 0x40)
driveType = DriveTypes.Removable;
else if ((sco.IDS.GenConfig & 0x40) == 0x40)
driveType = DriveTypes.Fixed;
else
driveType = DriveTypes.Unknown;
CloseHandle(handle);
textBox4.Text = DriveStrings[(int)driveType];
}
}
A perfectly working solution can be found here:
http://www.codeproject.com/Articles/16941/Get-Physical-HDD-Serial-Number-without-WMI
[edit]
Sorry, missed that a reference to this has already been submitted.
You can use the:
GetVolumeInformation
Win32 API function to get this information, if you must avoid WMI. The linked page gives full the declaration signature (in both VB & C#) for the API function along with sample code.
Your best options is windows api,
i made a simple search and got this
General processor info and also read this post
I am using hdd firmware track in my projects. I programmed behind the mdi form to look for hdd firmware number, then its looping on all the provided numbers of hdds of companies computers and if it matches anyone amongst these provided hdds firmware numbers, then run the applicatoin and load mdi form other wise provides a message "The application is not registed on this machine, please call Mr. Afridi to register this application on 00923339176357. My email address is munawar_s_afridi#yahoo.com. I will send complete source code of fetching how to programm professionaly hdd firmware number and how to stop others by using your app illegaly.
One lovely thing that you should specify all the company computers hdd firmware at once and let the application first pick the hdd firmware number, store it in a variable and then pick the value of this variable(a string value) and loop it one by one with each hdd number by using OR logical operator. If it finds a matching number amongst the companies hdds numbers with variable value, then app should load main form(mdi) other wise notify the user for registration.
The sample code will be provided using vb6. You can easily programm later on in vb.net just by understanding how to call unmanaged code in to a managed .net application. In this case a .dll.
I'm trying to "reset" the formatting in my RichTextBox (WinForms, not WPF). I was previously using
richTextBox.Text = richTextBox.Text;
However, that seems to have suddenly failed me. Now no matter what I set richTextBox.Text to, it retains some of the rtf formatting.
I've tried
richTextBox.Rtf = richTextBox.Text;
However, that complains about an incorrect format. There's gotta be a better way to do this. (Of course, selecting the entire thing, then resetting the back color, fore color, and font works, but that results in a flicker as the entire thing is selected then deselected, plus it's slower and requires a lot more code.) Anyone have any idea?
Edit:
I've gotten this to work:
string tempTxt = richTextBox.Text;
richTextBox.Clear();
richTextBox.Text = tempTxt;
But there has to be a better way, right?
Edit 2:
To be clear, I wish to remove all formatting while retaining the text. It looks like the code in the first edit will ship, unless anyone else has a more efficient/better coding way.
Edit 3:
richTextBox.Text = richTextBox.Text.ToString();
doesn't seem to work because it still doesn't clear all the formatting. The reason I don't like the method in the first Edit above is it makes the text box "flash" when it clears it then re-inputs the text. It seems like there should simply be a richTextBox.ResetFormatting() method, or some way to access the same functionality, as the Clear() method clearly (no pun intended) does some sort of formatting reset in addition to simply clearing all the text.
To summarize:
Is there a way (and if so, what is it) to reset the formatting of the text in a RichTextBox without clearing the text as in the example above (because that produces undesirable flashing)?
Saddly I've done my VERY best effort to slim this down to only the required code. It's still big, but it will work. The RichTextBox api in .Net is very limited, to do anything you almost have to thunk into the Win32 library. I've built a entire library around this thing just so I can toggle bold and determine if bold is actually set across the selection.
Usage:
RichTextBox te = ...;
te.ClearAllFormatting(new Font("Microsoft Sans Serif", 8.25f));
Tons of code:
static class RichTextExtensions
{
public static void ClearAllFormatting(this RichTextBox te, Font font)
{
CHARFORMAT2 fmt = new CHARFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.dwMask = CFM_ALL2;
fmt.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
fmt.szFaceName = font.FontFamily.Name;
double size = font.Size;
size /= 72;//logical dpi (pixels per inch)
size *= 1440.0;//twips per inch
fmt.yHeight = (int)size;//165
fmt.yOffset = 0;
fmt.crTextColor = 0;
fmt.bCharSet = 1;// DEFAULT_CHARSET;
fmt.bPitchAndFamily = 0;// DEFAULT_PITCH;
fmt.wWeight = 400;// FW_NORMAL;
fmt.sSpacing = 0;
fmt.crBackColor = 0;
//fmt.lcid = ???
fmt.dwMask &= ~CFM_LCID;//don't know how to get this...
fmt.dwReserved = 0;
fmt.sStyle = 0;
fmt.wKerning = 0;
fmt.bUnderlineType = 0;
fmt.bAnimation = 0;
fmt.bRevAuthor = 0;
fmt.bReserved1 = 0;
SendMessage(te.Handle, EM_SETCHARFORMAT, SCF_ALL, ref fmt);
}
private const UInt32 WM_USER = 0x0400;
private const UInt32 EM_GETCHARFORMAT = (WM_USER + 58);
private const UInt32 EM_SETCHARFORMAT = (WM_USER + 68);
private const UInt32 SCF_ALL = 0x0004;
private const UInt32 SCF_SELECTION = 0x0001;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, UInt32 wParam, ref CHARFORMAT2 lParam);
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
struct CHARFORMAT2
{
public int cbSize;
public uint dwMask;
public uint dwEffects;
public int yHeight;
public int yOffset;
public int crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szFaceName;
public short wWeight;
public short sSpacing;
public int crBackColor;
public int lcid;
public int dwReserved;
public short sStyle;
public short wKerning;
public byte bUnderlineType;
public byte bAnimation;
public byte bRevAuthor;
public byte bReserved1;
}
#region CFE_
// CHARFORMAT effects
const UInt32 CFE_BOLD = 0x0001;
const UInt32 CFE_ITALIC = 0x0002;
const UInt32 CFE_UNDERLINE = 0x0004;
const UInt32 CFE_STRIKEOUT = 0x0008;
const UInt32 CFE_PROTECTED = 0x0010;
const UInt32 CFE_LINK = 0x0020;
const UInt32 CFE_AUTOCOLOR = 0x40000000; // NOTE: this corresponds to
// CFM_COLOR, which controls it
// Masks and effects defined for CHARFORMAT2 -- an (*) indicates
// that the data is stored by RichEdit 2.0/3.0, but not displayed
const UInt32 CFE_SMALLCAPS = CFM_SMALLCAPS;
const UInt32 CFE_ALLCAPS = CFM_ALLCAPS;
const UInt32 CFE_HIDDEN = CFM_HIDDEN;
const UInt32 CFE_OUTLINE = CFM_OUTLINE;
const UInt32 CFE_SHADOW = CFM_SHADOW;
const UInt32 CFE_EMBOSS = CFM_EMBOSS;
const UInt32 CFE_IMPRINT = CFM_IMPRINT;
const UInt32 CFE_DISABLED = CFM_DISABLED;
const UInt32 CFE_REVISED = CFM_REVISED;
// CFE_AUTOCOLOR and CFE_AUTOBACKCOLOR correspond to CFM_COLOR and
// CFM_BACKCOLOR, respectively, which control them
const UInt32 CFE_AUTOBACKCOLOR = CFM_BACKCOLOR;
#endregion
#region CFM_
// CHARFORMAT masks
const UInt32 CFM_BOLD = 0x00000001;
const UInt32 CFM_ITALIC = 0x00000002;
const UInt32 CFM_UNDERLINE = 0x00000004;
const UInt32 CFM_STRIKEOUT = 0x00000008;
const UInt32 CFM_PROTECTED = 0x00000010;
const UInt32 CFM_LINK = 0x00000020; // Exchange hyperlink extension
const UInt32 CFM_SIZE = 0x80000000;
const UInt32 CFM_COLOR = 0x40000000;
const UInt32 CFM_FACE = 0x20000000;
const UInt32 CFM_OFFSET = 0x10000000;
const UInt32 CFM_CHARSET = 0x08000000;
const UInt32 CFM_SMALLCAPS = 0x0040; // (*)
const UInt32 CFM_ALLCAPS = 0x0080; // Displayed by 3.0
const UInt32 CFM_HIDDEN = 0x0100; // Hidden by 3.0
const UInt32 CFM_OUTLINE = 0x0200; // (*)
const UInt32 CFM_SHADOW = 0x0400; // (*)
const UInt32 CFM_EMBOSS = 0x0800; // (*)
const UInt32 CFM_IMPRINT = 0x1000; // (*)
const UInt32 CFM_DISABLED = 0x2000;
const UInt32 CFM_REVISED = 0x4000;
const UInt32 CFM_BACKCOLOR = 0x04000000;
const UInt32 CFM_LCID = 0x02000000;
const UInt32 CFM_UNDERLINETYPE = 0x00800000; // Many displayed by 3.0
const UInt32 CFM_WEIGHT = 0x00400000;
const UInt32 CFM_SPACING = 0x00200000; // Displayed by 3.0
const UInt32 CFM_KERNING = 0x00100000; // (*)
const UInt32 CFM_STYLE = 0x00080000; // (*)
const UInt32 CFM_ANIMATION = 0x00040000; // (*)
const UInt32 CFM_REVAUTHOR = 0x00008000;
const UInt32 CFE_SUBSCRIPT = 0x00010000; // Superscript and subscript are
const UInt32 CFE_SUPERSCRIPT = 0x00020000; // mutually exclusive
const UInt32 CFM_SUBSCRIPT = (CFE_SUBSCRIPT | CFE_SUPERSCRIPT);
const UInt32 CFM_SUPERSCRIPT = CFM_SUBSCRIPT;
// CHARFORMAT "ALL" masks
const UInt32 CFM_EFFECTS = (CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_COLOR |
CFM_STRIKEOUT | CFE_PROTECTED | CFM_LINK);
const UInt32 CFM_ALL = (CFM_EFFECTS | CFM_SIZE | CFM_FACE | CFM_OFFSET | CFM_CHARSET);
const UInt32 CFM_EFFECTS2 = (CFM_EFFECTS | CFM_DISABLED | CFM_SMALLCAPS | CFM_ALLCAPS
| CFM_HIDDEN | CFM_OUTLINE | CFM_SHADOW | CFM_EMBOSS
| CFM_IMPRINT | CFM_DISABLED | CFM_REVISED
| CFM_SUBSCRIPT | CFM_SUPERSCRIPT | CFM_BACKCOLOR);
const UInt32 CFM_ALL2 = (CFM_ALL | CFM_EFFECTS2 | CFM_BACKCOLOR | CFM_LCID
| CFM_UNDERLINETYPE | CFM_WEIGHT | CFM_REVAUTHOR
| CFM_SPACING | CFM_KERNING | CFM_STYLE | CFM_ANIMATION);
#endregion
}
More you ask?
I use most of this via a small utility class that wraps this for all the styles and font changes. This way you can change font-size and not change font name, etc.
class RichTextStyle
{
private readonly Control _textEdit;
private readonly CHARFORMAT2 _charFormat;
public RichTextStyle(RichTextBox te)
{
_textEdit = te;
_charFormat = new CHARFORMAT2();
_charFormat.cbSize = Marshal.SizeOf(_charFormat);
SendMessage(te.Handle, EM_GETCHARFORMAT, SCF_SELECTION, ref _charFormat);
}
private void SetEffect(UInt32 mask, UInt32 effect, bool valid)
{
CHARFORMAT2 fmt = new CHARFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.dwMask = mask;
fmt.dwEffects = valid ? effect : 0;
SendMessage(_textEdit.Handle, EM_SETCHARFORMAT, SCF_SELECTION, ref fmt);
}
private bool GetEffect(UInt32 mask, UInt32 effect)
{
return (0 != (_charFormat.dwMask & mask)) && (0 != (_charFormat.dwEffects & effect));
}
public bool Bold { get { return GetEffect(CFM_BOLD, CFE_BOLD); } set { SetEffect(CFM_BOLD, CFE_BOLD, value); } }
public bool Italic { get { return GetEffect(CFM_ITALIC, CFE_ITALIC); } set { SetEffect(CFM_ITALIC, CFE_ITALIC, value); } }
// ... etc ... etc ... you get the idea.
What about
richTextBox.Text = richTextBox.Text.ToString();
I have used
var t = richTextBox1.Text;
richTextBox1.Text = t;
EDIT::
be sure to insert a comment as to why you're doing what you're doing. To the unaware, it looks ridiculous.
Just using:
richTextBox1.Clear();
... Should do the trick. Works for me.
Another way I've found (and the one that I have switched to using, as it doesn't flash) is to grab the initial rtf string before any formatting is applied:
string initialRtf = richTextBox.Rtf;
Then, when I want to reset the formatting, I can just do:
richTextBox.Rtf = initialRtf;
However, this isn't really perfect, because it requires that the text stay the same and such. Well, at least it's a little better than the method detailed in the question.
"The reason I don't like the method in the first Edit above is it makes the text box "flash" when it clears it then re-inputs the text."
You should be able to implement the SuspendLayout() and ResumeLayout() methods.
string tempTxt = richTextBox.Text;
rtbIncludes.SuspendLayout();
richTextBox.Clear();
richTextBox.Text = tempTxt;
rtbIncludes.ResumeLayout();
SuspendLayout() and ResumeLayout() will stop the control from drawing while you manipulate the data. If the operation doesn't take to long, you will be able to clear the text and assign the unformatted text back without it appearing to flash on the screen.
If it does take too long, the control will appear as a black rectangle until ResumeLayout() is called.
For a while, I've been using this code in my own program. It sets the RTF of the RichTextBox directly, so should be much faster than setting styles the usual way. It takes in a string (the main text), and optionally also takes a Color array, font size array (int), and font-weight array (bool), each which represents every colour, size or font-weight for every character in the string.
Alternatively, you can simply keep the default size, weight, italic numbers given by the header.
public string text2RTF(string text, Color[] color = null, bool[] bold = null, int[] size = null,
string font = "Microsoft Sans Serif", double defaultFontSize = 16,
bool defaultFontBold = false, bool defaultFontItalic = false, char align = 'l')
{
StringBuilder rtf = new StringBuilder();
rtf.Append(#"{\rtf1\ansi\ansicpg1252\deff0\deflang2057{\fonttbl{\f0\fnil\fcharset0 ");
rtf.Append(font);
rtf.Append(#";}}{\colortbl ;");
if (color != null)
{
rtf.Append("\\red" + (color[0].R).ToString() + "\\green" + (color[0].G).ToString() + "\\blue" + (color[0].B).ToString() + ";");
for (int i = 1; i < text.Length; i++)
{
if ((color[i].R != color[i - 1].R || color[i].G != color[i - 1].G || color[i].B != color[i - 1].B))
{
rtf.Append("\\red" + (color[i].R).ToString() + "\\green" + (color[i].G).ToString() + "\\blue" + (color[i].B).ToString() + ";");
}
}
}
rtf.Append("}\n\\viewkind4\\uc1\\pard");
if (defaultFontBold == true) rtf.Append("\\b");
if (defaultFontItalic == true) rtf.Append("\\i");
if (align == 'r') rtf.Append("\\qr");
rtf.Append("\\f0\\fs" + (Math.Round(defaultFontSize)).ToString()+" ");
int startOfActualText = rtf.Length;
int count = 1;
for (int i = 0; i < text.Length; i++)
{
if (color!=null && (i == 0 || color[i].R != color[i - 1].R || color[i].G != color[i - 1].G || color[i].B != color[i - 1].B))
{
rtf.Append("\\cf"); rtf.Append(count.ToString() + " "); count++;
}
if (bold!=null && (i == 0 || bold[i] != bold[i - 1]))
{
if (bold[i] == true) rtf.Append("\\b1 ");
else rtf.Append("\\b0 ");
}
if (size!=null && (i == 0 || size[i] != size[i - 1]))
{
rtf.Append("\\fs"+size[i].ToString()+" " );
}
if (text[i] == '\\' || text[i] == '}' || text[i] == '{') rtf.Append('\\');
// GetRtfUnicodeOfChar:
string st="";
if (text[i] <= 0x7f) st = text[i].ToString();
else st = "\\u" + Convert.ToUInt32(text[i]) + "?";
rtf.Append(st);
}
rtf.Append("\n}");
rtf.Replace("\n", "\\par\n", startOfActualText, rtf.Length - startOfActualText);
return rtf.ToString();
}
I see that there are many answers, but I think that there is more simple and easy approach as the extension to clear all the formatting:
In my case I needed clear the formatting and leave an empty RichTextBox, therefore I made this function:
private void ClearRichTextBox()
{
this.richTextBox1.ForeColor = Color.Empty;
this.richTextBox1.BackColor = Color.Empty;
this.richTextBox1.SelectAll();
this.richTextBox1.SelectionColor = Color.Empty;
this.richTextBox1.SelectionBackColor = Color.Empty;
this.richTextBox1.SelectionFont = this.richTextBox1.Font;
this.richTextBox1.Clear();
}
Then the easy solution is:
string backUp = this.richTextBox1.Text;
ClearRichTextBox();
this.richTextBox1.Text = backUp;
Or simply remove the this.richTextBox1.Clear(); line in the clear function. (This will probably also work but I give no guarantee since I tested this only on simple formattings. Therefore it can be, that any other line should be added to remove a different formatting.)
When the text should be not cleared remember to store previous position/selection and refresh state after deformatting of data.
RichTextBox rtbTemp = new RichTextBox();
rtbTemp.Text = rtb.Text;
rtb.Rtf = rtbTemp.Rtf;
hope it works
works fine ..
var TempString = richTextBox1.Text;
richTextBox1.Rtf = string.Empty;
richTextBox1.Text = TempString ;