I'm trying to move a folder from directory to another directory , but I'm getting an exception of access to path is denied , so I found a c++ SHFileOperation method that can be used in this case, the problem is that I didn't have any idea how to use it:
public void MoveFolder(string oldPath,string newPath)
{
SHFILEOPSTRUCT hFILEOPSTRUCT = new SHFILEOPSTRUCT();
hFILEOPSTRUCT.pFrom = oldPath;
hFILEOPSTRUCT.pTo = newPath;
int res = SHFileOperation(ref hFILEOPSTRUCT);
}
[DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true,
ThrowOnUnmappableChar = true)]
[Obsolete]
static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
Struct definition of SHFILEOPSTRUCT:
[Obsolete("Use this element with caution and only if you know what you are doing. It's only meant to be used internally by MahApps.Metro and Fluent.Ribbon. Breaking changes might occur anytime without prior warning.")]
public struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
public FO wFunc;
public string pFrom;
public string pTo;
[CLSCompliant(false)]
public FOF fFlags;
public int fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}
}
This code throw an exception
Cannot marshal field 'fAnyOperationsAborted' of type 'ControlzEx.Standard.SHFILEOPSTRUCT': Invalid managed/unmanaged type combination (Int32/UInt32 must be paired with I4, U4, or Error).
How can I make this works?
I have a sub-window within a scroll window in a separate application. I am attempting to use a C# console application to inspect that scroll-window's true height (not its on screen height, but the height in pixels of how many pixels can be scrolled). I know using the existing user32.dll libs I can ask for a scroll info but that gives me details about the scrollbar itself, the scrollbar's height and position, but it doesn't give me the total pixels that the scrollbar would scroll through.
[DllImport("User32.dll")]
private static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref ScrollInfo lpsi);
Is there a way I can use the scrollinfo returned by the above method to derive the actual pixels of the scrollable area?
public struct ScrollInfo
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}
I kindly wanted to ask if it is recommendable to add properties for fields in a struct scope, if the struct is used for an winAPI call (f.ex. dllimport("xxx.dll")).
The question poped up when I let run the code Analysis - saying me, that I should use property accessors instead having public fields in struct.
And true, onthinking I would recommend that too, but - is an API call still possible with the 'so code optimized' struct?
May be I ought to show what I mean:
as everybody knows it:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct someAPICallStructure
{
public int cbSize;
public IntPtr hwndParent;
public string pszMessageText;
public string pszCaptionText;
public IntPtr hbmBanner;
}
as the code analyzer wishes:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct someAPICallStructure
{
public CBSize
{
get
{
return cbSize;
}
set
{
cbSize = value;
}
}
.... and properties for all other fields too ...
int cbSize;
IntPtr hwndParent;
string pszMessageText;
string pszCaptionText;
IntPtr hbmBanner;
}
Or could I even use like this?
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct someAPICallStructure
{
public CBSize {get; set;}
... and with all other fields too ...
}
And even further; can I add equals(..) and other suggested methods to the struct and it works still for the API Call?
I have a mouse and a touchpad on my laptop. I want a global hook for mousemove that tells me not only the new position, but also the physical device where it came from. Subscribing the hook only to the touchpad would be an even better solution, since I'm only interested in the touchpad. The hook has to work system wide (even if my application is not in focus).
How can I do this?
I'm not afraid to use Pinvoke in my C#/WPF application
You could use
P-Invoke user32.getrawinputdeviceinfo .
For mouse input you can get thing such:
[StructLayout(LayoutKind.Sequential)]
internal struct RID_DEVICE_INFO_MOUSE
{
[MarshalAs(UnmanagedType.U4)]
public int dwId;
[MarshalAs(UnmanagedType.U4)]
public int dwNumberOfButtons;
[MarshalAs(UnmanagedType.U4)]
public int dwSampleRate;
[MarshalAs(UnmanagedType.U4)]
public int fHasHorizontalWheel;
}
and, about Device:
StructLayout(LayoutKind.Sequential)]
internal struct RID_DEVICE_INFO_HID
{
[MarshalAs(UnmanagedType.U4)]
public int dwVendorId;
[MarshalAs(UnmanagedType.U4)]
public int dwProductId;
[MarshalAs(UnmanagedType.U4)]
public int dwVersionNumber;
[MarshalAs(UnmanagedType.U2)]
public ushort usUsagePage;
[MarshalAs(UnmanagedType.U2)]
public ushort usUsage;
}
I am trying to call a function from C# to a .DLL written in Borland C++ whose signature is:
extern "C" __declspec(dllexport) ls50errortype __stdcall Ls50P2Open(ls50p2apiconfiginfostruct &configinfo);
The corresponding call in C#:
[DllImport("C:\\Lumistar\\LDPS_8x\\Ls50P2_Dll.dll", EntryPoint = "Ls50P2Open", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall, CharSet = CharSet.Ansi, SetLastError = true)]
public static extern void Ls50P2Open(ref ls50p2apiconfiginfostruct configinfo);
The structure of interest (ls50p2apiconfiginfostruct) is composed of nested structures and enums (copied from the C++ header):
typedef enum
{
MFMODEL_LS50P1,
MFMODEL_4422PCI,
MFMODEL_LS50P2,
MFMODEL_LS70P2,
MFMODEL_LS5070,
MFMODEL_LAST
}ecardmodel;
typedef enum
{
CHANNELDEVICE_NONE,
CHANNELDEVICE_50,
CHANNELDEVICE_70,
CHANNELDEVICE_LAST
}ls50p2channeldevicetype;
typedef enum
{
LS50V2DCARD_NONE,
LS50V2DCARD_40V1_10,
LS50V2DCARD_40V1_20,
LS50V2DCARD_40V2_10,
LS50V2DCARD_40V2_20,
LS50V2DCARD_38,
LS50V2DCARD_LAST
}ls50p2daughtercardtype;
typedef struct
{
bool HasDaughterCard;
ls50p2daughtercardtype DCardType;
bool SpecialStatusCapable;
int MaxBitsyncInputs;
bool HasBitsyncConfidenceLevel;
bool HasBitsync2ndCh;
bool SpecialStatusCapable2ndCh;
bool HasBitsyncConfidenceLevel2ndCh;
ls50p2daughtercardtype DCardType2ndCh;
int MaxBitsyncInputs2ndCh;
}ls50p2daughtercardinfostruct;
typedef struct
{
ecardmodel DeviceModel;
ls50p2channeldevicetype ChannelDataTypeAry[2];
ls50p2daughtercardinfostruct DaughterCardInfo;
bool HasExtendedBertPatterns;
int FirmwareVersionAry[2];
int NumPremodFiltersAry[2];
double Ls50SimPreModFilterKhzAry[2][LS50V2_MAX50SIMPREMODFILTERS];
double Ls50SimMinFmDeviationKhzAry[2];
double Ls50SimMaxFmDeviationKhzAry[2];
}ls50p2cardconfigstruct;
typedef struct
{
unsigned char *DataBuf;
HANDLE hNewDataRdy;
DWORD MaxBufLength;
DWORD CurrentBufLength;
int NumHeaderBytes;
}ls50p2carddatastruct;
typedef struct
{
ls50p2cardconfigstruct CardConfigInfo[MAXMFCARDS];
int Ls50P2CardCount;
ls50p2carddatastruct DataInfo[MAXMFCARDS][2];
}ls50p2apiconfiginfostruct;
Here's the corresponding struct in C#:
public enum ecardmodel
{
MFMODEL_LS50P1,
MFMODEL_4422PCI,
MFMODEL_LS50P2,
MFMODEL_LS70P2,
MFMODEL_LS5070,
MFMODEL_LAST
}
public enum ls50p2channeldevicetype
{
CHANNELDEVICE_NONE,
CHANNELDEVICE_50,
CHANNELDEVICE_70,
CHANNELDEVICE_LAST
};
public enum ls50p2daughtercardtype
{
LS50V2DCARD_NONE,
LS50V2DCARD_40V1_10,
LS50V2DCARD_40V1_20,
LS50V2DCARD_40V2_10,
LS50V2DCARD_40V2_20,
LS50V2DCARD_38,
LS50V2DCARD_LAST
}
[StructLayout(LayoutKind.Sequential)]
public struct ls50p2daughtercardinfostruct
{
public bool HasDaughterCard;
public ls50p2daughtercardtype DCardType;
public bool SpecialStatusCapable;
public int MaxBitsyncInputs;
public bool HasBitsyncConfidenceLevel;
public bool HasBitsync2ndCh;
public bool SpecialStatusCapable2ndCh;
public bool HasBitsyncConfidenceLevel2ndCh;
public ls50p2daughtercardtype DCardType2ndCh;
public int MaxBitsyncInputs2ndCh;
}
[StructLayout(LayoutKind.Sequential)]
public struct ls50p2cardconfigstruct
{
public ecardmodel DeviceModel;
public ls50p2daughtercardtype[] ChannelDataTypeAry;
public ls50p2daughtercardinfostruct DaughterCardInfo;
public bool HasExtendedBertPatterns;
public int[] FirmwareVersionAry;
public int[] NumPremodFiltersAry;
public double[] Ls50SimPreModFilterKhzAry;
public double[] Ls50SimMinFmDeviationKhzAry;
public double[] Ls50SimMaxFmDeviationKhzAry;
}
[StructLayout(LayoutKind.Sequential)]
public struct ls50p2carddatastruct
{
public StringBuilder DataBuf;
public IntPtr hNewDataRdy;
public uint MaxBufLength;
public uint CurrentBufLength;
public int NumHeaderBytes;
}
[StructLayout(LayoutKind.Sequential)]
public struct ls50p2apiconfiginfostruct
{
public ls50p2cardconfigstruct[] CardConfigInfo;
public int Ls50P2CardCount;
public ls50p2carddatastruct[,] DataInfo;
}
Here's the code in C# that I use to call the function:
ls50p2apiconfiginfostruct lscfg = new ls50p2apiconfiginfostruct();
lscfg.CardConfigInfo = new ls50p2cardconfigstruct[8];
for (int i = 0; i < 8; i++)
{
lscfg.CardConfigInfo[i].ChannelDataTypeAry = new ls50p2daughtercardtype[2];
}
lscfg.DataInfo = new ls50p2carddatastruct[8, 2];
Ls50P2Open(ref lscfg);
I have tried making this struct in C# but I haven't had much success (problems with enums, 2D arrays, fixed sized buffers). What is the correct way to create this structure in C#? Would this need to be done in an unsafe context?
Now for some reason I get the following error when running the code:
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in Library.dll
Additional information: Old format or invalid type library. (Exception from HRESULT: 0x80028019 (TYPE_E_UNSUPFORMAT))
What does your C# structure looks like. Are you using the StructLayoutAttribute?
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx
You can use it with the option sequential so you just would have to fill your c# structure with fields in the right order.
I believe the array problem is more or less answered here; Improper marshaling: C# array to a C++ unmanaged array
The accepted answer shows how to safely marshal a dynamically allocated array.
As for the enums, they shouldn't pose any problems, there is a clean 1:1 mapping. In fact, I would do it as described in this msdn post; http://blogs.msdn.com/b/abhinaba/archive/2007/08/27/sharing-enums-across-c-and-c.aspx
You can simply define all your enums in a .cs file then include it in both projects and everything will work fine.