ShellExecuteEx returning Access Denied

T

Tony Pitman

I am trying to execute an external application from within a C# .NET Compact
Framework Assembly. I followed a suggested way of creating some helper
classes to marshal the string pointers for me. What I get is that the call
to ShellExecuteEx is failing and the Marshal.GetLastWin32Error returns
0x8000005 which is defined as Access Denied as far as I know.

At first I thought maybe it was that repllog.exe is not allowed to be called
in this way, so I tried to simply invoke calc.exe and that gives the same
results.

Here is the whole code: You might want to copy it out and into a dev
environ for better viewing. Basically the Memory class allocates memory for
the strings in the structure using local alloc and such. The StringPtr class
uses the Memory class to actually contain the strings and then the
SHELLEXECUTEINFO stuct uses the StringPtr to handle the strings.

With this in a project during debugging I have verified that the memory of
the structure does indeed look like it should and the strings are all
unicode style CE type strings and the memory addresses look right. So, why
do I get the access denied error from ShellExecuteEx?

namespace DotNetSyncMgr
{
public class Memory
{
[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalAlloc(int uFlags, int uBytes);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalFree(IntPtr hMem);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalReAlloc(IntPtr hMem, int uBytes, int
fuFlags);

private const int LMEM_FIXED = 0;
private const int LMEM_MOVEABLE = 2;
private const int LMEM_ZEROINIT = 0x40;
private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);

public static IntPtr AllocHLocal(int cb)
{
return LocalAlloc(LPTR, cb);
}

public static void FreeHLocal(IntPtr hLocal)
{
if (!hLocal.Equals(IntPtr.Zero))
{
if (!IntPtr.Zero.Equals(LocalFree(hLocal)))
{
throw (new Exception(Marshal.GetLastWin32Error().ToString()));
}

hLocal = IntPtr.Zero;
}
}

public static IntPtr ReAllocHLocal(IntPtr pv, int cb)
{
IntPtr newMem = LocalReAlloc(pv, cb, LMEM_MOVEABLE);
if (newMem.Equals(IntPtr.Zero))
{
throw (new OutOfMemoryException());
}

return newMem;
}

public static IntPtr StringToHLocalUni(string s)
{
if (s == "" || s == null)
return IntPtr.Zero;

int nc = s.Length;
int len = 2 * (1 + nc);
IntPtr hLocal = AllocHLocal(len);

if (hLocal.Equals(IntPtr.Zero))
throw (new OutOfMemoryException());
else
Marshal.Copy(s.ToCharArray(), 0, hLocal, s.Length);

return hLocal;
}
}

public struct StringPtr
{
private IntPtr szString;
public StringPtr(string s)
{
this.szString = Memory.StringToHLocalUni(s);
}

public override string ToString()
{
return Marshal.PtrToStringUni(this.szString);
}

public void Free()
{
Memory.FreeHLocal(this.szString);
}
}

[StructLayout(LayoutKind.Sequential)]
public struct SHELLEXECUTEINFO: IDisposable
{
public int cbSize;
public int fMask;
public int hwnd;
public StringPtr lpVerb;
public StringPtr lpFile;
public StringPtr lpParameters;
public StringPtr lpDirectory;
public int nShow;
public int hInstApp;
public int lpIDList;
public StringPtr lpClass;
public int hkeyClass;
public int dwHotKey;
public int hIcon;
public int hProcess;

public SHELLEXECUTEINFO(string lpVerb, string lpFile, string lpParameters,
string lpDirectory, string lpClass)
{
this.cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO));
this.fMask = 0;
this.hwnd = 0;
this.lpVerb = new StringPtr(lpVerb);
this.lpFile = new StringPtr(lpFile);
this.lpParameters = new StringPtr(lpParameters);
this.lpDirectory = new StringPtr(lpDirectory);
this.nShow = 0;
this.hInstApp = 0;
this.lpIDList = 0;
this.lpClass = new StringPtr(lpClass);
this.hkeyClass = 0;
this.dwHotKey = 0;
this.hIcon = 0;
this.hProcess = 0;
}

public void Dispose()
{
this.lpVerb.Free();
this.lpFile.Free();
this.lpParameters.Free();
this.lpDirectory.Free();
this.lpClass.Free();
}
}

/// <summary>
/// Summary description for SyncMgr.
/// </summary>
public class SyncMgr
{
[DllImport("shell32.dll", SetLastError = true)]
public static extern int ShellExecuteEx(SHELLEXECUTEINFO shInfo);

public SyncMgr()
{
}

public int Connect(string entryName)
{
SHELLEXECUTEINFO shInfo = new SHELLEXECUTEINFO(null, "calc.exe", null,
@"\Windows", null);

try
{
ShellExecuteEx(shInfo);
}
catch (Exception e)
{
MessageBox.Show(Marshal.GetLastWin32Error().ToString());
}

return 0;
}
}
}
 
A

Alex Feinman [MVP]

Tony,
In your code you are only checking the GetLastWin32Error() value in the
exception handler. Are you getting an exception from the call to
ShellExecuteEx? If so, what kind of exception?

Tony Pitman said:
I am trying to execute an external application from within a C# .NET Compact
Framework Assembly. I followed a suggested way of creating some helper
classes to marshal the string pointers for me. What I get is that the call
to ShellExecuteEx is failing and the Marshal.GetLastWin32Error returns
0x8000005 which is defined as Access Denied as far as I know.

At first I thought maybe it was that repllog.exe is not allowed to be called
in this way, so I tried to simply invoke calc.exe and that gives the same
results.

Here is the whole code: You might want to copy it out and into a dev
environ for better viewing. Basically the Memory class allocates memory for
the strings in the structure using local alloc and such. The StringPtr class
uses the Memory class to actually contain the strings and then the
SHELLEXECUTEINFO stuct uses the StringPtr to handle the strings.

With this in a project during debugging I have verified that the memory of
the structure does indeed look like it should and the strings are all
unicode style CE type strings and the memory addresses look right. So, why
do I get the access denied error from ShellExecuteEx?

namespace DotNetSyncMgr
{
public class Memory
{
[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalAlloc(int uFlags, int uBytes);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalFree(IntPtr hMem);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalReAlloc(IntPtr hMem, int uBytes, int
fuFlags);

private const int LMEM_FIXED = 0;
private const int LMEM_MOVEABLE = 2;
private const int LMEM_ZEROINIT = 0x40;
private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);

public static IntPtr AllocHLocal(int cb)
{
return LocalAlloc(LPTR, cb);
}

public static void FreeHLocal(IntPtr hLocal)
{
if (!hLocal.Equals(IntPtr.Zero))
{
if (!IntPtr.Zero.Equals(LocalFree(hLocal)))
{
throw (new Exception(Marshal.GetLastWin32Error().ToString()));
}

hLocal = IntPtr.Zero;
}
}

public static IntPtr ReAllocHLocal(IntPtr pv, int cb)
{
IntPtr newMem = LocalReAlloc(pv, cb, LMEM_MOVEABLE);
if (newMem.Equals(IntPtr.Zero))
{
throw (new OutOfMemoryException());
}

return newMem;
}

public static IntPtr StringToHLocalUni(string s)
{
if (s == "" || s == null)
return IntPtr.Zero;

int nc = s.Length;
int len = 2 * (1 + nc);
IntPtr hLocal = AllocHLocal(len);

if (hLocal.Equals(IntPtr.Zero))
throw (new OutOfMemoryException());
else
Marshal.Copy(s.ToCharArray(), 0, hLocal, s.Length);

return hLocal;
}
}

public struct StringPtr
{
private IntPtr szString;
public StringPtr(string s)
{
this.szString = Memory.StringToHLocalUni(s);
}

public override string ToString()
{
return Marshal.PtrToStringUni(this.szString);
}

public void Free()
{
Memory.FreeHLocal(this.szString);
}
}

[StructLayout(LayoutKind.Sequential)]
public struct SHELLEXECUTEINFO: IDisposable
{
public int cbSize;
public int fMask;
public int hwnd;
public StringPtr lpVerb;
public StringPtr lpFile;
public StringPtr lpParameters;
public StringPtr lpDirectory;
public int nShow;
public int hInstApp;
public int lpIDList;
public StringPtr lpClass;
public int hkeyClass;
public int dwHotKey;
public int hIcon;
public int hProcess;

public SHELLEXECUTEINFO(string lpVerb, string lpFile, string lpParameters,
string lpDirectory, string lpClass)
{
this.cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO));
this.fMask = 0;
this.hwnd = 0;
this.lpVerb = new StringPtr(lpVerb);
this.lpFile = new StringPtr(lpFile);
this.lpParameters = new StringPtr(lpParameters);
this.lpDirectory = new StringPtr(lpDirectory);
this.nShow = 0;
this.hInstApp = 0;
this.lpIDList = 0;
this.lpClass = new StringPtr(lpClass);
this.hkeyClass = 0;
this.dwHotKey = 0;
this.hIcon = 0;
this.hProcess = 0;
}

public void Dispose()
{
this.lpVerb.Free();
this.lpFile.Free();
this.lpParameters.Free();
this.lpDirectory.Free();
this.lpClass.Free();
}
}

/// <summary>
/// Summary description for SyncMgr.
/// </summary>
public class SyncMgr
{
[DllImport("shell32.dll", SetLastError = true)]
public static extern int ShellExecuteEx(SHELLEXECUTEINFO shInfo);

public SyncMgr()
{
}

public int Connect(string entryName)
{
SHELLEXECUTEINFO shInfo = new SHELLEXECUTEINFO(null, "calc.exe", null,
@"\Windows", null);

try
{
ShellExecuteEx(shInfo);
}
catch (Exception e)
{
MessageBox.Show(Marshal.GetLastWin32Error().ToString());
}

return 0;
}
}
}
 
A

Alex Feinman [MVP]

Never mind. The problem is in your P/Invoke definition for ShellExecuteEx.
It needs to pass SHELLEXECUTEINFO by ref or declare it as a class.
In addition ShellExecuteEx is exported from coredll.dll (as are most API
functions in Windows CE)
[DllImport("coredll.dll", SetLastError = true)]
public static extern int ShellExecuteEx(ref SHELLEXECUTEINFO shInfo);

Invoke as:
ShellExecuteEx(ref shInfo);

GetLastWin32Error is useless if a managed exception has occured.

Tony Pitman said:
I am trying to execute an external application from within a C# .NET Compact
Framework Assembly. I followed a suggested way of creating some helper
classes to marshal the string pointers for me. What I get is that the call
to ShellExecuteEx is failing and the Marshal.GetLastWin32Error returns
0x8000005 which is defined as Access Denied as far as I know.

At first I thought maybe it was that repllog.exe is not allowed to be called
in this way, so I tried to simply invoke calc.exe and that gives the same
results.

Here is the whole code: You might want to copy it out and into a dev
environ for better viewing. Basically the Memory class allocates memory for
the strings in the structure using local alloc and such. The StringPtr class
uses the Memory class to actually contain the strings and then the
SHELLEXECUTEINFO stuct uses the StringPtr to handle the strings.

With this in a project during debugging I have verified that the memory of
the structure does indeed look like it should and the strings are all
unicode style CE type strings and the memory addresses look right. So, why
do I get the access denied error from ShellExecuteEx?

namespace DotNetSyncMgr
{
public class Memory
{
[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalAlloc(int uFlags, int uBytes);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalFree(IntPtr hMem);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalReAlloc(IntPtr hMem, int uBytes, int
fuFlags);

private const int LMEM_FIXED = 0;
private const int LMEM_MOVEABLE = 2;
private const int LMEM_ZEROINIT = 0x40;
private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);

public static IntPtr AllocHLocal(int cb)
{
return LocalAlloc(LPTR, cb);
}

public static void FreeHLocal(IntPtr hLocal)
{
if (!hLocal.Equals(IntPtr.Zero))
{
if (!IntPtr.Zero.Equals(LocalFree(hLocal)))
{
throw (new Exception(Marshal.GetLastWin32Error().ToString()));
}

hLocal = IntPtr.Zero;
}
}

public static IntPtr ReAllocHLocal(IntPtr pv, int cb)
{
IntPtr newMem = LocalReAlloc(pv, cb, LMEM_MOVEABLE);
if (newMem.Equals(IntPtr.Zero))
{
throw (new OutOfMemoryException());
}

return newMem;
}

public static IntPtr StringToHLocalUni(string s)
{
if (s == "" || s == null)
return IntPtr.Zero;

int nc = s.Length;
int len = 2 * (1 + nc);
IntPtr hLocal = AllocHLocal(len);

if (hLocal.Equals(IntPtr.Zero))
throw (new OutOfMemoryException());
else
Marshal.Copy(s.ToCharArray(), 0, hLocal, s.Length);

return hLocal;
}
}

public struct StringPtr
{
private IntPtr szString;
public StringPtr(string s)
{
this.szString = Memory.StringToHLocalUni(s);
}

public override string ToString()
{
return Marshal.PtrToStringUni(this.szString);
}

public void Free()
{
Memory.FreeHLocal(this.szString);
}
}

[StructLayout(LayoutKind.Sequential)]
public struct SHELLEXECUTEINFO: IDisposable
{
public int cbSize;
public int fMask;
public int hwnd;
public StringPtr lpVerb;
public StringPtr lpFile;
public StringPtr lpParameters;
public StringPtr lpDirectory;
public int nShow;
public int hInstApp;
public int lpIDList;
public StringPtr lpClass;
public int hkeyClass;
public int dwHotKey;
public int hIcon;
public int hProcess;

public SHELLEXECUTEINFO(string lpVerb, string lpFile, string lpParameters,
string lpDirectory, string lpClass)
{
this.cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO));
this.fMask = 0;
this.hwnd = 0;
this.lpVerb = new StringPtr(lpVerb);
this.lpFile = new StringPtr(lpFile);
this.lpParameters = new StringPtr(lpParameters);
this.lpDirectory = new StringPtr(lpDirectory);
this.nShow = 0;
this.hInstApp = 0;
this.lpIDList = 0;
this.lpClass = new StringPtr(lpClass);
this.hkeyClass = 0;
this.dwHotKey = 0;
this.hIcon = 0;
this.hProcess = 0;
}

public void Dispose()
{
this.lpVerb.Free();
this.lpFile.Free();
this.lpParameters.Free();
this.lpDirectory.Free();
this.lpClass.Free();
}
}

/// <summary>
/// Summary description for SyncMgr.
/// </summary>
public class SyncMgr
{
[DllImport("shell32.dll", SetLastError = true)]
public static extern int ShellExecuteEx(SHELLEXECUTEINFO shInfo);

public SyncMgr()
{
}

public int Connect(string entryName)
{
SHELLEXECUTEINFO shInfo = new SHELLEXECUTEINFO(null, "calc.exe", null,
@"\Windows", null);

try
{
ShellExecuteEx(shInfo);
}
catch (Exception e)
{
MessageBox.Show(Marshal.GetLastWin32Error().ToString());
}

return 0;
}
}
}
 
T

Tony Pitman

Alex,

I had already figured out the coredll.dll problem, but thanks for pointing
it out in case someone else is having that problem.

I was getting a managed exception. It must have been from the fact that I
was trying to pass a struct to a dll function call. I am guessing that I
should put my GetLastWin32Error call right after the function call because I
would not be getting a managed exception, right?

Changing the SHELLEXECUTEINFO structure to a class worked great. Thanks for
the help. Now I can get on with doing what I really wanted to.

Do you have any idea which DLL the Ras functions are in? I need to call some
Ras functions like RasDial and such. If they are not in a DLL is there some
kind of .NET version of them that works on the Compact Framework?

Thanks again for the help,

Tony Pitman

Alex Feinman said:
Never mind. The problem is in your P/Invoke definition for ShellExecuteEx.
It needs to pass SHELLEXECUTEINFO by ref or declare it as a class.
In addition ShellExecuteEx is exported from coredll.dll (as are most API
functions in Windows CE)
[DllImport("coredll.dll", SetLastError = true)]
public static extern int ShellExecuteEx(ref SHELLEXECUTEINFO shInfo);

Invoke as:
ShellExecuteEx(ref shInfo);

GetLastWin32Error is useless if a managed exception has occured.

Tony Pitman said:
I am trying to execute an external application from within a C# .NET Compact
Framework Assembly. I followed a suggested way of creating some helper
classes to marshal the string pointers for me. What I get is that the call
to ShellExecuteEx is failing and the Marshal.GetLastWin32Error returns
0x8000005 which is defined as Access Denied as far as I know.

At first I thought maybe it was that repllog.exe is not allowed to be called
in this way, so I tried to simply invoke calc.exe and that gives the same
results.

Here is the whole code: You might want to copy it out and into a dev
environ for better viewing. Basically the Memory class allocates memory for
the strings in the structure using local alloc and such. The StringPtr class
uses the Memory class to actually contain the strings and then the
SHELLEXECUTEINFO stuct uses the StringPtr to handle the strings.

With this in a project during debugging I have verified that the memory of
the structure does indeed look like it should and the strings are all
unicode style CE type strings and the memory addresses look right. So, why
do I get the access denied error from ShellExecuteEx?

namespace DotNetSyncMgr
{
public class Memory
{
[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalAlloc(int uFlags, int uBytes);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalFree(IntPtr hMem);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalReAlloc(IntPtr hMem, int uBytes, int
fuFlags);

private const int LMEM_FIXED = 0;
private const int LMEM_MOVEABLE = 2;
private const int LMEM_ZEROINIT = 0x40;
private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);

public static IntPtr AllocHLocal(int cb)
{
return LocalAlloc(LPTR, cb);
}

public static void FreeHLocal(IntPtr hLocal)
{
if (!hLocal.Equals(IntPtr.Zero))
{
if (!IntPtr.Zero.Equals(LocalFree(hLocal)))
{
throw (new Exception(Marshal.GetLastWin32Error().ToString()));
}

hLocal = IntPtr.Zero;
}
}

public static IntPtr ReAllocHLocal(IntPtr pv, int cb)
{
IntPtr newMem = LocalReAlloc(pv, cb, LMEM_MOVEABLE);
if (newMem.Equals(IntPtr.Zero))
{
throw (new OutOfMemoryException());
}

return newMem;
}

public static IntPtr StringToHLocalUni(string s)
{
if (s == "" || s == null)
return IntPtr.Zero;

int nc = s.Length;
int len = 2 * (1 + nc);
IntPtr hLocal = AllocHLocal(len);

if (hLocal.Equals(IntPtr.Zero))
throw (new OutOfMemoryException());
else
Marshal.Copy(s.ToCharArray(), 0, hLocal, s.Length);

return hLocal;
}
}

public struct StringPtr
{
private IntPtr szString;
public StringPtr(string s)
{
this.szString = Memory.StringToHLocalUni(s);
}

public override string ToString()
{
return Marshal.PtrToStringUni(this.szString);
}

public void Free()
{
Memory.FreeHLocal(this.szString);
}
}

[StructLayout(LayoutKind.Sequential)]
public struct SHELLEXECUTEINFO: IDisposable
{
public int cbSize;
public int fMask;
public int hwnd;
public StringPtr lpVerb;
public StringPtr lpFile;
public StringPtr lpParameters;
public StringPtr lpDirectory;
public int nShow;
public int hInstApp;
public int lpIDList;
public StringPtr lpClass;
public int hkeyClass;
public int dwHotKey;
public int hIcon;
public int hProcess;

public SHELLEXECUTEINFO(string lpVerb, string lpFile, string lpParameters,
string lpDirectory, string lpClass)
{
this.cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO));
this.fMask = 0;
this.hwnd = 0;
this.lpVerb = new StringPtr(lpVerb);
this.lpFile = new StringPtr(lpFile);
this.lpParameters = new StringPtr(lpParameters);
this.lpDirectory = new StringPtr(lpDirectory);
this.nShow = 0;
this.hInstApp = 0;
this.lpIDList = 0;
this.lpClass = new StringPtr(lpClass);
this.hkeyClass = 0;
this.dwHotKey = 0;
this.hIcon = 0;
this.hProcess = 0;
}

public void Dispose()
{
this.lpVerb.Free();
this.lpFile.Free();
this.lpParameters.Free();
this.lpDirectory.Free();
this.lpClass.Free();
}
}

/// <summary>
/// Summary description for SyncMgr.
/// </summary>
public class SyncMgr
{
[DllImport("shell32.dll", SetLastError = true)]
public static extern int ShellExecuteEx(SHELLEXECUTEINFO shInfo);

public SyncMgr()
{
}

public int Connect(string entryName)
{
SHELLEXECUTEINFO shInfo = new SHELLEXECUTEINFO(null, "calc.exe", null,
@"\Windows", null);

try
{
ShellExecuteEx(shInfo);
}
catch (Exception e)
{
MessageBox.Show(Marshal.GetLastWin32Error().ToString());
}

return 0;
}
}
}
 
A

Alex Feinman [MVP]

RAS functions are in the coredll too. You may want to check
http://www.intelliprog.com/netcf/ras.html for an existing commercial wrapper

Tony Pitman said:
Alex,

I had already figured out the coredll.dll problem, but thanks for pointing
it out in case someone else is having that problem.

I was getting a managed exception. It must have been from the fact that I
was trying to pass a struct to a dll function call. I am guessing that I
should put my GetLastWin32Error call right after the function call because I
would not be getting a managed exception, right?

Changing the SHELLEXECUTEINFO structure to a class worked great. Thanks for
the help. Now I can get on with doing what I really wanted to.

Do you have any idea which DLL the Ras functions are in? I need to call some
Ras functions like RasDial and such. If they are not in a DLL is there some
kind of .NET version of them that works on the Compact Framework?

Thanks again for the help,

Tony Pitman

Alex Feinman said:
Never mind. The problem is in your P/Invoke definition for ShellExecuteEx.
It needs to pass SHELLEXECUTEINFO by ref or declare it as a class.
In addition ShellExecuteEx is exported from coredll.dll (as are most API
functions in Windows CE)
[DllImport("coredll.dll", SetLastError = true)]
public static extern int ShellExecuteEx(ref SHELLEXECUTEINFO shInfo);

Invoke as:
ShellExecuteEx(ref shInfo);

GetLastWin32Error is useless if a managed exception has occured.

Tony Pitman said:
I am trying to execute an external application from within a C# .NET Compact
Framework Assembly. I followed a suggested way of creating some helper
classes to marshal the string pointers for me. What I get is that the call
to ShellExecuteEx is failing and the Marshal.GetLastWin32Error returns
0x8000005 which is defined as Access Denied as far as I know.

At first I thought maybe it was that repllog.exe is not allowed to be called
in this way, so I tried to simply invoke calc.exe and that gives the same
results.

Here is the whole code: You might want to copy it out and into a dev
environ for better viewing. Basically the Memory class allocates
memory
for
the strings in the structure using local alloc and such. The StringPtr class
uses the Memory class to actually contain the strings and then the
SHELLEXECUTEINFO stuct uses the StringPtr to handle the strings.

With this in a project during debugging I have verified that the
memory
of
the structure does indeed look like it should and the strings are all
unicode style CE type strings and the memory addresses look right. So, why
do I get the access denied error from ShellExecuteEx?

namespace DotNetSyncMgr
{
public class Memory
{
[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalAlloc(int uFlags, int uBytes);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalFree(IntPtr hMem);

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr LocalReAlloc(IntPtr hMem, int uBytes, int
fuFlags);

private const int LMEM_FIXED = 0;
private const int LMEM_MOVEABLE = 2;
private const int LMEM_ZEROINIT = 0x40;
private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);

public static IntPtr AllocHLocal(int cb)
{
return LocalAlloc(LPTR, cb);
}

public static void FreeHLocal(IntPtr hLocal)
{
if (!hLocal.Equals(IntPtr.Zero))
{
if (!IntPtr.Zero.Equals(LocalFree(hLocal)))
{
throw (new Exception(Marshal.GetLastWin32Error().ToString()));
}

hLocal = IntPtr.Zero;
}
}

public static IntPtr ReAllocHLocal(IntPtr pv, int cb)
{
IntPtr newMem = LocalReAlloc(pv, cb, LMEM_MOVEABLE);
if (newMem.Equals(IntPtr.Zero))
{
throw (new OutOfMemoryException());
}

return newMem;
}

public static IntPtr StringToHLocalUni(string s)
{
if (s == "" || s == null)
return IntPtr.Zero;

int nc = s.Length;
int len = 2 * (1 + nc);
IntPtr hLocal = AllocHLocal(len);

if (hLocal.Equals(IntPtr.Zero))
throw (new OutOfMemoryException());
else
Marshal.Copy(s.ToCharArray(), 0, hLocal, s.Length);

return hLocal;
}
}

public struct StringPtr
{
private IntPtr szString;
public StringPtr(string s)
{
this.szString = Memory.StringToHLocalUni(s);
}

public override string ToString()
{
return Marshal.PtrToStringUni(this.szString);
}

public void Free()
{
Memory.FreeHLocal(this.szString);
}
}

[StructLayout(LayoutKind.Sequential)]
public struct SHELLEXECUTEINFO: IDisposable
{
public int cbSize;
public int fMask;
public int hwnd;
public StringPtr lpVerb;
public StringPtr lpFile;
public StringPtr lpParameters;
public StringPtr lpDirectory;
public int nShow;
public int hInstApp;
public int lpIDList;
public StringPtr lpClass;
public int hkeyClass;
public int dwHotKey;
public int hIcon;
public int hProcess;

public SHELLEXECUTEINFO(string lpVerb, string lpFile, string lpParameters,
string lpDirectory, string lpClass)
{
this.cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO));
this.fMask = 0;
this.hwnd = 0;
this.lpVerb = new StringPtr(lpVerb);
this.lpFile = new StringPtr(lpFile);
this.lpParameters = new StringPtr(lpParameters);
this.lpDirectory = new StringPtr(lpDirectory);
this.nShow = 0;
this.hInstApp = 0;
this.lpIDList = 0;
this.lpClass = new StringPtr(lpClass);
this.hkeyClass = 0;
this.dwHotKey = 0;
this.hIcon = 0;
this.hProcess = 0;
}

public void Dispose()
{
this.lpVerb.Free();
this.lpFile.Free();
this.lpParameters.Free();
this.lpDirectory.Free();
this.lpClass.Free();
}
}

/// <summary>
/// Summary description for SyncMgr.
/// </summary>
public class SyncMgr
{
[DllImport("shell32.dll", SetLastError = true)]
public static extern int ShellExecuteEx(SHELLEXECUTEINFO shInfo);

public SyncMgr()
{
}

public int Connect(string entryName)
{
SHELLEXECUTEINFO shInfo = new SHELLEXECUTEINFO(null, "calc.exe", null,
@"\Windows", null);

try
{
ShellExecuteEx(shInfo);
}
catch (Exception e)
{
MessageBox.Show(Marshal.GetLastWin32Error().ToString());
}

return 0;
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top