I'm automaticly downloading a whole folder from my Dropbox - storage(?), via the weblink eg:https://www.dropbox.com/sh/bunchOfLetters/somthnsomthn?dl=1 with just a basic webclient:
using (WebClient wc = new WebClient())
{
wc.DownloadFile(new Uri(uri), _basePath + localPath);
}
The folder naturaly comes as a .rar file (due to Dropbox's download system), and if i try to open the file manualy (via Winrar) there is no problem at all. Now comes the problem.... if i try to use any kind of automated libary (like unrar or SharpCompress) it always gives my a 'Corupted Header' as if the download wouldnt have gotten everythng or the file just broke ..but still opening it with Winrar works just fine.
If anyone has an idea how and why; i would be greatfull to hear your thoughts.
Edit:
here is the function i use for SharpCompress:
public static bool ExtractToFolder(string extractionPackage, string outputPath)
{
if (extractionPackage == null) throw new ArgumentNullException(nameof(extractionPackage));
if (outputPath == null) throw new ArgumentNullException(nameof(outputPath));
if (string.IsNullOrEmpty(extractionPackage))
throw new ArgumentException("Argument is null or empty", nameof(extractionPackage));
if (string.IsNullOrEmpty(outputPath))
throw new ArgumentException("Argument is null or empty", nameof(outputPath));
if (!extractionPackage.EndsWith(".rar")) throw new InvalidDataException("not a .rar File");
Directory.CreateDirectory(outputPath);
try
{
using (Stream stream = File.OpenRead(extractionPackage))
using (RarReader reader = RarReader.Open(stream))
{
while (reader.MoveToNextEntry())
{
reader.WriteEntryToDirectory(outputPath, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite);
}
}
return true;
}
catch
{
return false;
}
}
and if someone is interested in the unrar one:
..i know its not well done but it still works for normal files...just not Dropbox ones
namespace Cryptus.Rar
{
/// <summary>
/// just for compatibility purposes, use <see cref="SharpCompress"/>
/// </summary>
public class Unrar
{
public enum RarOperations
{
OP_EXTRACT = 0,
OP_TEST = 1,
OP_LIST = 2
}
public const int ERAR_END_ARCHIVE = 10;
public const int ERAR_NO_MEMORY = 11;
public const int ERAR_BAD_DATA = 12;
public const int ERAR_BAD_ARCHIVE = 13;
public const int ERAR_UNKNOWN_FORMAT = 14;
public const int ERAR_EOPEN = 15;
public const int ERAR_ECREATE = 16;
public const int ERAR_ECLOSE = 17;
public const int ERAR_EREAD = 18;
public const int ERAR_EWRITE = 19;
public const int ERAR_SMALL_BUF = 20;
public const int RAR_OM_LIST = 0;
public const int RAR_OM_EXTRACT = 1;
public const int RAR_SKIP = 0;
public const int RAR_TEST = 1;
public const int RAR_EXTRACT = 2;
public const int RAR_VOL_ASK = 0;
public const int RAR_VOL_NOTIFY = 1;
[DllImport("unrar.dll")]
public static extern IntPtr RAROpenArchive(ref RAROpenArchiveData ArchiveData);
[DllImport("unrar.dll")]
public static extern int RARCloseArchive(IntPtr hArcData);
[DllImport("unrar.dll")]
public static extern int RARReadHeader(IntPtr hArcData, ref RARHeaderData HeaderData);
[DllImport("unrar.dll")]
public static extern IntPtr RAROpenArchiveEx(ref RAROpenArchiveDataEx ArchiveData);
[DllImport("unrar.dll")]
public static extern int RARReadHeaderEx(IntPtr hArcData, ref RARHeaderDataEx HeaderData);
[DllImport("unrar.dll")]
public static extern int RARProcessFile(IntPtr hArcData, int Operation, string DestPath, string DestName);
[DllImport("unrar.dll")]
public static extern int RARGetDllVersion();
[DllImport("user32.dll")]
private static extern bool CharToOem(string lpszSrc, [Out] StringBuilder lpszDst);
/// <summary>
/// opens an arcive and unloads its content to destDolder
/// </summary>
/// <param name="strFileName">input .rar File</param>
/// <param name="destFolder">destination Folder</param>
public void UnloadArchieve(string strFileName, string destFolder)
{
IntPtr lHandle;
int iStatus;
RAROpenArchiveData uRAR = new RAROpenArchiveData();
RARHeaderData uHeader = new RARHeaderData();
uRAR.ArcName = strFileName + char.MinValue;
uRAR.OpenMode = RAR_OM_EXTRACT;
uRAR.CmtBuf = null;
string ExtractDir = Path.GetDirectoryName(strFileName);
StringBuilder sbDir = new StringBuilder();
CharToOem(destFolder, sbDir);
lHandle = RAROpenArchive(ref uRAR);
if (uRAR.OpenResult != 0)
Console.Write("Unable to open the Archieve!!!");
while (RARReadHeader(lHandle, ref uHeader) == 0)
{
int result = RARProcessFile(lHandle, 2, sbDir.ToString(), null);
if (0 != result)
Console.Write("Unable to open the Archieve!!!");
}
iStatus = RARCloseArchive(lHandle);
}
[StructLayout(LayoutKind.Sequential)]
public struct RARHeaderData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string ArcName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string FileName;
public uint Flags;
public uint PackSize;
public uint UnpSize;
public uint HostOS;
public uint FileCRC;
public uint FileTime;
public uint UnpVer;
public uint Method;
public uint FileAttr;
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
}
[StructLayout(LayoutKind.Sequential)]
public struct RAROpenArchiveData
{
public string ArcName;
public uint OpenMode;
public uint OpenResult;
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
}
[StructLayout(LayoutKind.Sequential)]
public struct RAROpenArchiveDataEx
{
public string ArcName;
public string ArcNameW;
public uint OpenMode;
public uint OpenResult;
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
public uint Flags;
public uint Reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct RARHeaderDataEx
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string ArcName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string FileName;
public string FileNameW;
public uint Flags;
public uint PackSize;
public uint PackSizeHigh;
public uint UnpSize;
public uint UnpSizeHigh;
public uint HostOS;
public uint FileCRC;
public uint FileTime;
public uint UnpVer;
public uint Method;
public uint FileAttr;
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
public uint Reserved;
}
}
Ok so it seems that #smarx was right with his comment! Its a bit strange, but Dropbox generates .rar files which contain not a rar, but a zip header. This is no problem for any form of automatic detection of the header format, but if you use a rar extraction method (which should be used for .rar files..) it wont work.
Related
I have the below code to change my 2nd display screen resolution. It all works fine and changes as expected. However once it has been changed my mouse/cursor is offset. eg the active location is not where the pointer shows on the screen.
Thoughts?
using System;
using System.Windows;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE1
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmPosition;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
};
class User_32
{
[DllImport("user32.dll")]
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags);
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettingsEx(string lpszDeviceName, ref DEVMODE1 lpDevMode, IntPtr hwnd, ChangeDisplaySettingsFlags dwflags, IntPtr lParam);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int CDS_UPDATEREGISTRY = 0x01;
public const int CDS_TEST = 0x02;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_RESTART = 1;
public const int DISP_CHANGE_FAILED = -1;
[Flags()]
public enum ChangeDisplaySettingsFlags : uint{
CDS_NONE = 0,
CDS_UPDATEREGISTRY = 0x00000001,
CDS_TEST = 0x00000002,
CDS_FULLSCREEN = 0x00000004,
CDS_GLOBAL = 0x00000008,
CDS_SET_PRIMARY = 0x00000010,
CDS_VIDEOPARAMETERS = 0x00000020,
CDS_ENABLE_UNSAFE_MODES = 0x00000100,
CDS_DISABLE_UNSAFE_MODES = 0x00000200,
CDS_RESET = 0x40000000,
CDS_RESET_EX = 0x20000000,
CDS_NORESET = 0x10000000
}
}
namespace Resolution
{
class CResolution
{
public CResolution(int iWidth, int iHeight)
{
DEVMODE1 dm = new DEVMODE1();
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
dm.dmPosition = 2;
if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm))
{
dm.dmPelsWidth = iWidth;
dm.dmPelsHeight = iHeight;
long result = User_32.ChangeDisplaySettingsEx("\\\\.\\DISPLAY2", ref dm, IntPtr.Zero, User_32.ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);
}
}
}
}
-
static void Main(string[] args)
{
Resolution.CResolution ChangeRes = new Resolution.CResolution(2560, 1600);
}
I can switch between Landsacpe and Portrait mode in one screen by using the following code (That I have done this morning). And the problem is I have two screens in a computer. And I want the screen 1 is LANDSCAPE mode, and the screen 2 is PORTRAIT mode. But I don't know how to modify the code to make it work. (Sorry about my English)
class ModeSetting
{
public const int LANDSCAPE = 0;
public const int PORTRAIT = 1;
public static bool ChangeMode(int screenID, int modeID)
{
//I'm not using screenID here. Let me know how to do that. How to get screenID
//Or anything that help me.
DEVMODE dm = new DEVMODE();
dm.dmDeviceName = new string(new char[32]);
dm.dmFormName = new string(new char[32]);
//dm.dmSize = Marshal.SizeOf(dm);
if (modeID != PORTRAIT) modeID = LANDSCAPE;
if (0 != NativeMethods.EnumDisplaySettings(
null,
NativeMethods.ENUM_CURRENT_SETTINGS,
ref dm))
{
int temp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = temp;
dm.dmDisplayOrientation = modeID;
int iRet = NativeMethods.ChangeDisplaySettings(ref dm, 0);
Console.WriteLine(iRet);
if (NativeMethods.DISP_CHANGE_SUCCESSFUL != iRet)
{
return false;
}
return true;
}
return false;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public int dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
internal class NativeMethods
{
// PInvoke declaration for EnumDisplaySettings Win32 API
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern int EnumDisplaySettings(
string lpszDeviceName,
int iModeNum,
ref DEVMODE lpDevMode);
// PInvoke declaration for ChangeDisplaySettings Win32 API
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern int ChangeDisplaySettings(
ref DEVMODE lpDevMode,
int dwFlags);
// constants
public const int ENUM_CURRENT_SETTINGS = -1;
public const int DMDO_DEFAULT = 0;
public const int DMDO_90 = 1;
public const int DMDO_180 = 2;
public const int DMDO_270 = 3;
public const int DISP_CHANGE_SUCCESSFUL = 0;
}
}
And I can switch between LANDSCAPE and PORTRAIT mode by using:
ModeSetting.ChangeMode(0, ModeSetting.LANDSCAPE);//0 here is screen ID that I cannot do when two screens
ModeSetting.ChangeMode(0, ModeSetting.PORTRAIT);
I've seen How do I get all installed fixed-width fonts?, but I can't make it work:
internal class NativeMethods
{
public const Int32 LF_FACESIZE = 32;
public const Int32 FIXED_PITCH = 1;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class LOGFONT
{
public Int32 lfHeight = 0;
public Int32 lfWidth = 0;
public Int32 lfEscapement = 0;
public Int32 lfOrientation = 0;
public Int32 lfWeight = 0;
public Byte lfItalic = 0;
public Byte lfUnderline = 0;
public Byte lfStrikeOut = 0;
public Byte lfCharSet = 0;
public Byte lfOutPrecision = 0;
public Byte lfClipPrecision = 0;
public Byte lfQuality = 0;
public Byte lfPitchAndFamily = 0;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)]
public String lfFaceName = string.Empty;
}
}
public partial class MainForm : Form
{
private string font_names = null;
public MainForm()
{
InitializeComponent();
StringBuilder sb = new StringBuilder();
foreach (var font_family in FontFamily.Families)
{
if (font_family.IsStyleAvailable(FontStyle.Regular))
{
var lf = new NativeMethods.LOGFONT();
Font font = new Font(font_family, 9.0f);
font.ToLogFont(lf);
if ((lf.lfPitchAndFamily & 0x3) == NativeMethods.FIXED_PITCH)
{
sb.AppendLine(font_family.Name);
}
}
}
font_names = sb.ToString();
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawString(font_names, SystemFonts.MessageBoxFont, SystemBrushes.WindowText, 10.0f, 10.0f);
}
}
It seem no matter what font it is, the lfPitchAndFamily is always zero.
So how get all monospaced fonts?
I think I'll just use P/Invoke to do this:
internal class NativeMethods
{
public const Int32 LF_FACESIZE = 32;
public const Int32 LF_FULLFACESIZE = 64;
public const Int32 DEFAULT_CHARSET = 1;
public const Int32 FIXED_PITCH = 1;
public const Int32 TRUETYPE_FONTTYPE = 0x0004;
public delegate Int32 FONTENUMPROC(ref ENUMLOGFONT lpelf, ref NEWTEXTMETRIC lpntm, UInt32 FontType, IntPtr lParam);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LOGFONT
{
public Int32 lfHeight;
public Int32 lfWidth;
public Int32 lfEscapement;
public Int32 lfOrientation;
public Int32 lfWeight;
public Byte lfItalic;
public Byte lfUnderline;
public Byte lfStrikeOut;
public Byte lfCharSet;
public Byte lfOutPrecision;
public Byte lfClipPrecision;
public Byte lfQuality;
public Byte lfPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)]
public String lfFaceName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct TEXTMETRIC
{
public Int32 tmHeight;
public Int32 tmAscent;
public Int32 tmDescent;
public Int32 tmInternalLeading;
public Int32 tmExternalLeading;
public Int32 tmAveCharWidth;
public Int32 tmMaxCharWidth;
public Int32 tmWeight;
public Int32 tmOverhang;
public Int32 tmDigitizedAspectX;
public Int32 tmDigitizedAspectY;
public Char tmFirstChar;
public Char tmLastChar;
public Char tmDefaultChar;
public Char tmBreakChar;
public Byte tmItalic;
public Byte tmUnderlined;
public Byte tmStruckOut;
public Byte tmPitchAndFamily;
public Byte tmCharSet;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct ENUMLOGFONT
{
public LOGFONT elfLogFont;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FULLFACESIZE)]
public String elfFullName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)]
public String elfStyle;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct NEWTEXTMETRIC
{
public Int32 tmHeight;
public Int32 tmAscent;
public Int32 tmDescent;
public Int32 tmInternalLeading;
public Int32 tmExternalLeading;
public Int32 tmAveCharWidth;
public Int32 tmMaxCharWidth;
public Int32 tmWeight;
public Int32 tmOverhang;
public Int32 tmDigitizedAspectX;
public Int32 tmDigitizedAspectY;
public Char tmFirstChar;
public Char tmLastChar;
public Char tmDefaultChar;
public Char tmBreakChar;
public Byte tmItalic;
public Byte tmUnderlined;
public Byte tmStruckOut;
public Byte tmPitchAndFamily;
public Byte tmCharSet;
public UInt32 ntmFlags;
public UInt32 ntmSizeEM;
public UInt32 ntmCellHeight;
public UInt32 ntmAvgWidth;
}
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public extern static Int32 EnumFontFamiliesEx(IntPtr hdc, ref LOGFONT lpLogfont, FONTENUMPROC lpEnumFontFamExProc, IntPtr lParam, UInt32 dwFlags);
}
internal static class Program
{
private static void Main()
{
Graphics graphics = Graphics.FromHwnd(IntPtr.Zero);
IntPtr hdc = graphics.GetHdc();
var logfont = new NativeMethods.LOGFONT() { lfCharSet = NativeMethods.DEFAULT_CHARSET };
NativeMethods.EnumFontFamiliesEx(hdc, ref logfont, new NativeMethods.FONTENUMPROC(EnumFontFamExProc), IntPtr.Zero, 0);
graphics.ReleaseHdc();
}
private static int EnumFontFamExProc(ref NativeMethods.ENUMLOGFONT lpelf, ref NativeMethods.NEWTEXTMETRIC lpntm, uint FontType, IntPtr lParam)
{
if ((lpelf.elfLogFont.lfPitchAndFamily & 0x3) == NativeMethods.FIXED_PITCH)
{
Console.WriteLine(lpelf.elfLogFont.lfFaceName);
}
return 1;
}
}
I want to get in my c# app the name of the file type, that is shown in file properties in windows... for example .log file has the type as LOG file (.log) or .bat has Batch file for Windows (.bat)(translated from my lang, so maybe not accurate).
Please, where can i find this info? or how to get to this?
i found Get-Registered-File-Types-and-Their-Associated-Ico article, where the autor shows how to get the icon, but not the type name of file that is showed in OS.
You have to call the respective Shell function SHGetFileInfo, which is a native Win32 API.
class NativeMethods
{
private const int FILE_ATTRIBUTE_NORMAL = 0x80;
private const int SHGFI_TYPENAME = 0x400;
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr SHGetFileInfo(
string pszPath,
int dwFileAttributes,
ref SHFILEINFO shinfo,
uint cbfileInfo,
int uFlags);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero;
iIcon = 0;
dwAttributes = 0;
szDisplayName = "";
szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
public static string GetShellFileType(string fileName)
{
var shinfo = new SHFILEINFO(true);
const int flags = SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES;
if (SHGetFileInfo(fileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags) == IntPtr.Zero)
{
return "File";
}
return shinfo.szTypeName;
}
}
Then, simply call NativeMethods.GetShellFileType("...").
You can read that info from the registry
use like GetDescription("cpp") or GetDescription(".xml")
public static string ReadDefaultValue(string regKey)
{
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(regKey, false))
{
if (key != null)
{
return key.GetValue("") as string;
}
}
return null;
}
public static string GetDescription(string ext)
{
if (ext.StartsWith(".") && ext.Length > 1) ext = ext.Substring(1);
var retVal = ReadDefaultValue(ext + "file");
if (!String.IsNullOrEmpty(retVal)) return retVal;
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("." + ext, false))
{
if (key == null) return "";
using (var subkey = key.OpenSubKey("OpenWithProgids"))
{
if (subkey == null) return "";
var names = subkey.GetValueNames();
if (names == null || names.Length == 0) return "";
foreach (var name in names)
{
retVal = ReadDefaultValue(name);
if (!String.IsNullOrEmpty(retVal)) return retVal;
}
}
}
return "";
}
You can get this information using the SHGetFileInfo.
using System;
using System.Runtime.InteropServices;
namespace GetFileTypeAndDescription
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr i = Win32.SHGetFileInfo(#"d:\temp\test.xls", 0, ref
shinfo,(uint)Marshal.SizeOf(shinfo),Win32.SHGFI_TY PENAME);
string s = Convert.ToString(shinfo.szTypeName.Trim());
Console.WriteLine(s);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
class Win32
{
public const uint SHGFI_DISPLAYNAME = 0x00000200;
public const uint SHGFI_TYPENAME = 0x400;
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
public const uint SHGFI_SMALLICON = 0x1; // 'Small icon
[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint
dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
}
}
you have to use the shgetfileinfo, see below link for some code:
http://www.pinvoke.net/default.aspx/shell32.shgetfileinfo
Please let me know how could i record and save audio file to my hard drive by using c# code.
I already downloaded code from one of the technical web page.
That may be i don't know enough that it can support recording and saving function as well.
Please let me show you some of my downloaded Code so that you can give me any suggestion how should i do.
[WaveIn.CS]
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace SoundViewer
{
internal class WaveInHelper
{
public static void Try(int err)
{
if (err != WaveNative.MMSYSERR_NOERROR)
throw new Exception(err.ToString());
}
}
public delegate void BufferDoneEventHandler(IntPtr data, int size);
internal class WaveInBuffer : IDisposable
{
public WaveInBuffer NextBuffer;
private AutoResetEvent m_RecordEvent = new AutoResetEvent(false);
private IntPtr m_WaveIn;
private WaveNative.WaveHdr m_Header;
private byte[] m_HeaderData;
private GCHandle m_HeaderHandle;
private GCHandle m_HeaderDataHandle;
private bool m_Recording;
internal static void WaveInProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WIM_DATA)
{
try
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveInBuffer buf = (WaveInBuffer)h.Target;
buf.OnCompleted();
}
catch
{
}
}
}
public WaveInBuffer(IntPtr waveInHandle, int size)
{
m_WaveIn = waveInHandle;
m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned);
m_Header.dwUser = (IntPtr)GCHandle.Alloc(this);
m_HeaderData = new byte[size];
m_HeaderDataHandle = GCHandle.Alloc(m_HeaderData, GCHandleType.Pinned);
m_Header.lpData = m_HeaderDataHandle.AddrOfPinnedObject();
m_Header.dwBufferLength = size;
WaveInHelper.Try(WaveNative.waveInPrepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)));
}
~WaveInBuffer()
{
Dispose();
}
public void Dispose()
{
if (m_Header.lpData != IntPtr.Zero)
{
WaveNative.waveInUnprepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header));
m_HeaderHandle.Free();
m_Header.lpData = IntPtr.Zero;
}
m_RecordEvent.Close();
if (m_HeaderDataHandle.IsAllocated)
m_HeaderDataHandle.Free();
GC.SuppressFinalize(this);
}
public int Size
{
get { return m_Header.dwBufferLength; }
}
public IntPtr Data
{
get { return m_Header.lpData; }
}
public bool Record()
{
lock(this)
{
m_RecordEvent.Reset();
m_Recording = WaveNative.waveInAddBuffer(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)) == WaveNative.MMSYSERR_NOERROR;
System.Diagnostics.Debug.Write(string.Format("\n m_WaveIn: {0}, m_Header.dwBytesRecorded: {1}", m_WaveIn, m_Header.dwBytesRecorded));
//m_WaveIn.ToPointer();
return m_Recording;
}
}
public void WaitFor()
{
if (m_Recording)
m_Recording = m_RecordEvent.WaitOne();
else
Thread.Sleep(0);
}
private void OnCompleted()
{
m_RecordEvent.Set();
m_Recording = false;
}
}
public class WaveInRecorder : IDisposable
{
private IntPtr m_WaveIn;
private WaveInBuffer m_Buffers; // linked list
private WaveInBuffer m_CurrentBuffer;
private Thread m_Thread;
private BufferDoneEventHandler m_DoneProc;
private bool m_Finished;
private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveInBuffer.WaveInProc);
public static int DeviceCount
{
get { return WaveNative.waveInGetNumDevs(); }
}
public WaveInRecorder(int device, WaveFormat format, int bufferSize, int bufferCount, BufferDoneEventHandler doneProc)
{
m_DoneProc = doneProc;
WaveInHelper.Try(WaveNative.waveInOpen(out m_WaveIn, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
AllocateBuffers(bufferSize, bufferCount);
for (int i = 0; i < bufferCount; i++)
{
SelectNextBuffer();
m_CurrentBuffer.Record();
}
WaveInHelper.Try(WaveNative.waveInStart(m_WaveIn));
m_Thread = new Thread(new ThreadStart(ThreadProc));
m_Thread.Start();
}
public void Recording()
{
//int rawsize = Marshal.SizeOf(m_WaveIn);
//byte[] rawdata = new byte[256 * 1024];
////Marshal.Copy(m_WaveIn, rawdata, 0, rawsize);
////System.IO.File.WriteAllBytes(string.Format("C:\\TempImage\\audio_{0}.wav", Guid.NewGuid()), rawdata );
//Marshal.Copy(rawdata, 0, m_WaveIn, rawdata.Length);
////System.IO.File.WriteAllBytes(string.Format("C:\\TempImage\\audio_{0}.wav", Guid.NewGuid()), rawdata);
////Marshal.FreeHGlobal(m_WaveIn);
//System.IO.MemoryStream ms = new System.IO.MemoryStream(
//int elementSize = Marshal.SizeOf(typeof(IntPtr));
//System.Diagnostics.Debug.Print("Reading unmanaged memory:");
//// Print the 10 elements of the C-style unmanagedArray
//for (int i = 0; i < 10; i++)
//{
// System.Diagnostics.Debug.Print(Marshal.ReadIntPtr(m_WaveIn, i * elementSize));
//}
}
~WaveInRecorder()
{
Dispose();
}
public void Dispose()
{
if (m_Thread != null)
try
{
m_Finished = true;
if (m_WaveIn != IntPtr.Zero)
WaveNative.waveInReset(m_WaveIn);
WaitForAllBuffers();
m_Thread.Join();
m_DoneProc = null;
FreeBuffers();
if (m_WaveIn != IntPtr.Zero)
WaveNative.waveInClose(m_WaveIn);
}
finally
{
m_Thread = null;
m_WaveIn = IntPtr.Zero;
}
GC.SuppressFinalize(this);
}
private void ThreadProc()
{
while (!m_Finished)
{
Advance();
if (m_DoneProc != null && !m_Finished)
m_DoneProc(m_CurrentBuffer.Data, m_CurrentBuffer.Size);
m_CurrentBuffer.Record();
}
}
private void AllocateBuffers(int bufferSize, int bufferCount)
{
FreeBuffers();
if (bufferCount > 0)
{
m_Buffers = new WaveInBuffer(m_WaveIn, bufferSize);
WaveInBuffer Prev = m_Buffers;
try
{
for (int i = 1; i < bufferCount; i++)
{
WaveInBuffer Buf = new WaveInBuffer(m_WaveIn, bufferSize);
Prev.NextBuffer = Buf;
Prev = Buf;
}
}
finally
{
Prev.NextBuffer = m_Buffers;
}
}
}
private void FreeBuffers()
{
m_CurrentBuffer = null;
if (m_Buffers != null)
{
WaveInBuffer First = m_Buffers;
m_Buffers = null;
WaveInBuffer Current = First;
do
{
WaveInBuffer Next = Current.NextBuffer;
Current.Dispose();
Current = Next;
} while(Current != First);
}
}
private void Advance()
{
SelectNextBuffer();
m_CurrentBuffer.WaitFor();
}
private void SelectNextBuffer()
{
m_CurrentBuffer = m_CurrentBuffer == null ? m_Buffers : m_CurrentBuffer.NextBuffer;
}
private void WaitForAllBuffers()
{
WaveInBuffer Buf = m_Buffers;
while (Buf.NextBuffer != m_Buffers)
{
Buf.WaitFor();
Buf = Buf.NextBuffer;
}
}
}
}
[WaveNative.cs]
internal class WaveNative
{
// consts
public const int MMSYSERR_NOERROR = 0; // no error
public const int MM_WOM_OPEN = 0x3BB;
public const int MM_WOM_CLOSE = 0x3BC;
public const int MM_WOM_DONE = 0x3BD;
public const int MM_WIM_OPEN = 0x3BE;
public const int MM_WIM_CLOSE = 0x3BF;
public const int MM_WIM_DATA = 0x3C0;
public const int CALLBACK_FUNCTION = 0x00030000; // dwCallback is a FARPROC
public const int TIME_MS = 0x0001; // time in milliseconds
public const int TIME_SAMPLES = 0x0002; // number of wave samples
public const int TIME_BYTES = 0x0004; // current byte offset
// callbacks
public delegate void WaveDelegate(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2);
// structs
[StructLayout(LayoutKind.Sequential)] public struct WaveHdr
{
public IntPtr lpData; // pointer to locked data buffer
public int dwBufferLength; // length of data buffer
public int dwBytesRecorded; // used for input only
public IntPtr dwUser; // for client's use
public int dwFlags; // assorted flags (see defines)
public int dwLoops; // loop control counter
public IntPtr lpNext; // PWaveHdr, reserved for driver
public int reserved; // reserved for driver
}
private const string mmdll = "winmm.dll";
// WaveOut calls
[DllImport(mmdll)]
public static extern int waveOutGetNumDevs();
[DllImport(mmdll)]
public static extern int waveOutPrepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutUnprepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutWrite(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveOutReset(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutClose(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutPause(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutRestart(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutGetPosition(IntPtr hWaveOut, out int lpInfo, int uSize);
[DllImport(mmdll)]
public static extern int waveOutSetVolume(IntPtr hWaveOut, int dwVolume);
[DllImport(mmdll)]
public static extern int waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);
// WaveIn calls
[DllImport(mmdll)]
public static extern int waveInGetNumDevs();
[DllImport(mmdll)]
public static extern int waveInAddBuffer(IntPtr hwi, ref WaveHdr pwh, int cbwh);
[DllImport(mmdll)]
public static extern int waveInClose(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInOpen(out IntPtr phwi, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveInUnprepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveInReset(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInStart(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInStop(IntPtr hwi);
}