Re: managed / unmanged - StringToHGlobalAnsi / PtrToStringAnsi
- From: "Bram Hoefnagel" <bhoefnagel@xxxxxxxxxxx>
- Date: 2 Dec 2005 01:42:22 -0800
I've put the code together with dllimports and struct into a test
project, hope you see what's wrong.
Bram.
[StructLayout(LayoutKind.Sequential)]
public struct SERVICE_FAILURE_ACTIONS
{
[MarshalAs(UnmanagedType.U4)]
public int dwResetPeriod;
//[MarshalAs(UnmanagedType.LPTStr)]
//public string lpRebootMsg;
//[MarshalAs(UnmanagedType.LPTStr)]
//public string lpCommand;
[MarshalAs(UnmanagedType.U4)]
public int lpRebootMsg;
[MarshalAs(UnmanagedType.U4)]
public int lpCommand;
[MarshalAs(UnmanagedType.U4)]
public int cActions;
[MarshalAs(UnmanagedType.U4)]
public int lpsaActions;
}
[DllImport("advapi32.dll")]
public static extern IntPtr OpenSCManager(string lpMachineName, string
lpDatabaseName, int dwDesiredAccess);
[DllImport("advapi32.dll")]
public static extern IntPtr OpenService(IntPtr hSCManager, string
lpServiceName, int dwDesiredAccess);
[DllImport("advapi32.dll")]
public static extern IntPtr LockServiceDatabase(IntPtr hSCManager);
[DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig2")]
public static extern bool ChangeServiceFailureActions(IntPtr hService,
int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref
SERVICE_FAILURE_ACTIONS lpInfo);
[DllImport("advapi32.dll", EntryPoint = "QueryServiceConfig2A", CharSet
= CharSet.Ansi)]
public static extern bool QueryServiceConfiguration(IntPtr hService,
int dwInfoLevel, IntPtr lpInfo, uint size, ref uint bytesneeded);
[DllImport("advapi32.dll")]
public static extern bool CloseServiceHandle(IntPtr hSCObject);
[DllImport("advapi32.dll")]
public static extern bool UnlockServiceDatabase(IntPtr hSCManager);
private const int SC_MANAGER_ALL_ACCESS = 0xF003F;
private const int SERVICE_ALL_ACCESS = 0xF01FF;
private const int SERVICE_CONFIG_FAILURE_ACTIONS = 0x2;
private const int SERVICE_NO_CHANGE = -1;
private const int ERROR_ACCESS_DENIED = 5;
public ArrayList FailureActions;
private void SetFailureActions()
{ //Register the failure actions
FailureActions.Clear();
FailureActions.Add(new FailureAction(RecoverAction.Restart,
60000));
FailureActions.Add(new FailureAction(RecoverAction.RunCommand,
2000));
FailureActions.Add(new FailureAction(RecoverAction.None, 3000));
IntPtr scmHndl = IntPtr.Zero;
IntPtr svcHndl = IntPtr.Zero;
IntPtr tmpBuf = IntPtr.Zero;
IntPtr svcLock = IntPtr.Zero;
IntPtr tmpMsg = IntPtr.Zero;
IntPtr tmpCmd = IntPtr.Zero;
try
{
scmHndl = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
svcLock = LockServiceDatabase(scmHndl);
svcHndl = OpenService(scmHndl, "MyServiceName",
SERVICE_ALL_ACCESS);
int numActions = FailureActions.Count;
int[] actions = new int[numActions * 2];
int currInd = 0;
foreach (FailureAction fa in FailureActions)
{
actions[currInd] = (int)fa.Type;
actions[++currInd] = fa.Delay;
currInd++;
//If the FailureActions is reboot then Grand shutdown
privilege
}
tmpBuf = Marshal.AllocHGlobal(numActions * 8);
Marshal.Copy(actions, 0, tmpBuf, numActions * 2);
tmpCmd = Marshal.StringToHGlobalAnsi("MyCommand.exe");
tmpMsg = Marshal.StringToHGlobalAnsi("Time to reboot!");
//tmpMsg = Marshal.StringToHGlobalUni("Time to reboot!");
SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();
sfa.cActions = numActions;
sfa.dwResetPeriod = SERVICE_NO_CHANGE;
//sfa.lpCommand = "My Test Command";
//sfa.lpRebootMsg = "My Reboot Message";
sfa.lpCommand = tmpCmd.ToInt32();
sfa.lpRebootMsg = tmpMsg.ToInt32();
sfa.lpsaActions = tmpBuf.ToInt32();
bool rslt = ChangeServiceFailureActions(svcHndl,
SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa);
Marshal.FreeHGlobal(tmpBuf); tmpBuf = IntPtr.Zero;
}
catch (Exception ex)
{ Console.WriteLine(ex.Message); }
finally
{
if (scmHndl != IntPtr.Zero)
{ if (svcLock != IntPtr.Zero)
{ UnlockServiceDatabase(svcLock);
svcLock = IntPtr.Zero; }
CloseServiceHandle(scmHndl);
scmHndl = IntPtr.Zero; }
if (svcHndl != IntPtr.Zero)
{ CloseServiceHandle(svcHndl);
svcHndl = IntPtr.Zero; }
if (tmpBuf != IntPtr.Zero)
{ Marshal.FreeHGlobal(tmpBuf);
tmpBuf = IntPtr.Zero; }
}
}
private void GetFailureActions()
{
IntPtr scmHndl = IntPtr.Zero;
IntPtr svcHndl = IntPtr.Zero;
IntPtr tmpBuf = IntPtr.Zero;
IntPtr nullValue = new IntPtr(0);
try
{
scmHndl = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
svcHndl = OpenService(scmHndl, "MyServiceName",
SERVICE_ALL_ACCESS);
uint dwBytesNeeded = 8192;
SERVICE_FAILURE_ACTIONS sfa;
bool fRet = QueryServiceConfiguration(svcHndl,
SERVICE_CONFIG_FAILURE_ACTIONS, nullValue, 0, ref dwBytesNeeded);
IntPtr unmanagedArray =
Marshal.AllocHGlobal((int)dwBytesNeeded);
fRet = QueryServiceConfiguration(svcHndl,
SERVICE_CONFIG_FAILURE_ACTIONS, unmanagedArray, dwBytesNeeded, ref
dwBytesNeeded);
sfa =
(SERVICE_FAILURE_ACTIONS)Marshal.PtrToStructure(unmanagedArray,
typeof(SERVICE_FAILURE_ACTIONS));
//Why are the sfa.lpRebootMsg and lpCommand Pointers below,
incorrect??
string reboot = Marshal.PtrToStringAnsi(new
IntPtr(sfa.lpRebootMsg));
string command = Marshal.PtrToStringAnsi(new
IntPtr(sfa.lpCommand));
//string command = Marshal.PtrToStringUni(new
IntPtr(sfa.lpCommand));
Int32[] bins = new Int32[sfa.cActions * 2];
int offset = sfa.lpsaActions;
for (int i = 0; i < sfa.cActions * 2; i++)
{ bins[i]=((Int32)Marshal.ReadIntPtr(new IntPtr(offset + i *
4))); }
Marshal.Release(unmanagedArray);
}
catch (Exception ex)
{ Console.WriteLine(ex.Message); }
}
public enum RecoverAction{ None=0, Restart=1, Reboot=2, RunCommand=3 }
public class FailureAction
{
private RecoverAction type = RecoverAction.None;
private int delay=0;
public FailureAction(){}
public FailureAction( RecoverAction actionType, int actionDelay ){
this.type = actionType;
this.delay = actionDelay;
}
public RecoverAction Type{ get{ return type; } set{ type = value;}
}
public int Delay{ get{ return delay; } set{ delay = value;} }
}
.
- Follow-Ups:
- Re: managed / unmanged - StringToHGlobalAnsi / PtrToStringAnsi
- From: Willy Denoyette [MVP]
- Re: managed / unmanged - StringToHGlobalAnsi / PtrToStringAnsi
- From: Bram Hoefnagel
- Re: managed / unmanged - StringToHGlobalAnsi / PtrToStringAnsi
- Prev by Date: RE: Passing an array of structures from c# to c++
- Next by Date: ActiveX component can't create object
- Previous by thread: RE: Passing an array of structures from c# to c++
- Next by thread: Re: managed / unmanged - StringToHGlobalAnsi / PtrToStringAnsi
- Index(es):
Relevant Pages
|