As I was using my PC today, I came across the idea that I wanted to close a running application, and be able to re-open it later in exactly the same state. I noted that this was exactly the same sort of behaviour as you get when you Hibernate your PC, so I started digging around for a way to accomplish a "Hibernate" of an application, without actually turning off the PC.
I haven't been able to find anything relevant so far, so I was wondering if anyone had any ideas A method/api call/something that will save the state of a program to disk (just as Hibernate does), and can recall it from disk at a later date
There's got to be a way of doing this, maybe I'm just using the wrong search term
Any help would be fantastic!

Re-creating Hibernate Functionality
Buck_Danny
There's no magic way to do this AFAIK, however using .NET Serialization you can accomplish what you want (though it may not be easy). Using serialization allows you to persist object state to a data store and then retrieve that data and reconstruct the objects. There are two types of serialization supported in .NET, binary serialization and Xml Serialization. Binary serialization will allow you to write an objects entire state (both public and private members) to a binary stream which you can then store in a file. Xml Serialization allows you serialize an object's state to Xml. In this case as you are simply dumping the state and retrieving it back, binary serialization may be your best bet. However only objects that are marked with a [Serialization] attribute or that implement the ISerializable interface can be serialized. DataSets and Collections (any class that implements ICollection / IEnumerable) for example are serializable, however if the object within the collection is not also serializable then it will fail. For example windows forms are not serializable. If you put a windows form in a collection and try to serialize it, that will fail.
That being said, nothing stops you from creating your own FormState class that contains the data about the form that you want to serialize for example position, height, etc. Technically you can also add a collection of ControlState classes that contain the data about your controls that you wish to persist state on as well (though I wouldn't recommend it). When you want to serialize (in this scenaior) you create an instance for FormState class, and set the approriate properties. Next you iterate through each of your child controls on the form, and for each control you create a ControlState instance setting the appopriate properties. Each ControlState instance is then added to the FormState's ControlState collection. Finall you serialize the FormState itself.
Let's use an example as an illustration. Let's say I have an AddressBook application that lets me create addresses. Addresses are stored in a database, but I can create as many addresses as I want in memory and then decide to save them or discard them. My app UI is very simple, I have one form which displays a list of names and addresses in a grid, along with a splitter bar and a panel that contains a single address record. Each address that is either loaded from the database or created in memory, is stored in an Address class instance. This class has been added as a datasource to my project, and both the Address grid and the detail are bound to it. As the app launches, it retrieves the full list of addresses from the database, and then populates the list. All addresses are stored in a private _Addresses collection. As I click on an name in the list, the full details for the address are displayed in the second panel. When I create a new record, it is edited it in the detail panel.
My address class definition is posted below. I've marked it as serializable so that I will be able to save it's state.
[Serializable]
public class Address {
public Address() {
}
private long _AddressID;
public long AddressID {..}
private string _Name;
public string Name {..}
private string _City;
public string City {..}
private string _State;
public State State {..}
private string _Zip;
public string Zip {..}
private string _Phone;
public string Phone {..}
}
So now I want my app to have a 'Suspend' feature. When I suspend the app I want it to save my form size, positioning, as well as the size of the top panel, as I might have moved the splitter. Additionally I want to save any addresses that I have created in memory and that have not yet been saved to disk. Let's ignore existing records that have been edited in memory but not yet saved for now, as that is a more complex case. So in order to save the state of my app I create an ApplicationState class that contains both my form state and my list of addresses.
[Serializable]
public class ApplicationState {
public ApplicationState(FormState formState, List<Address> addresses) {
..
}
private FormState _FormState;
public FormState FormState {..}
private List<Address> Addresses;
public List<Address> Addresses {..}
}
[Serializable]
public class FormState {
public FormState(long height, long width, long top, long left, long addressListHeight) {
..
}
private long _Height;
public long Height {..}
private long _Width;
public long Width {..}
private long _Top;
public long Top {..}
private long _Left;
public long Left {..}
private long _AddressListHeight;
public long AddressListHeight {..}
}
Notice that my FormState only save's minimal data as these are the pieces of information I want to persist. The rest of my form properties such as fonts, etc are set during my normal form initialization. So now let's look at the code to save and resume state.
public static void SaveState(AddressForm addressForm, List<Address> addresses) {
//create a new app state instance passing in the form state and list of addreses
ApplicationState AppState = new ApplicationState(
new FormState(addressForm.Height, addressForm.Width, addressForm.Top, addressForm.Left,
addressForm.AddressListPanel.Height), addresses
);
IFormatter Formatter = new BinaryFormatter();
//create the stream to write out to
Stream SaveStream = new FileStream("AddressBook.adb", FileMode.Create, FileAccess.Write, FileShare.None);
//serialize to the stream
formatter.Serialize(SaveStream, AppState);
//close it
SaveStream.Close();
);
}
public static void ResumeState(AddressForm addressForm, ref List<Address> addresses) {
IFormatter Formatter = new BinaryFormatter();
//create the stream to read
Stream LoadStream = new FileStream("AddressBook.adb", FileMode.Open, FileAccess.Read, FileShare.Read);
//deserialize the app state from the stream
ApplicationState AppState = (ApplicationState) formatter.Deserialize(stream);
stream.Close();
//set the address form based on the from state
addressForm.Height = AppState.FormState.Height;
addressForm.Width = AppState.FormState.Width;
addressForm.Top = AppState.FormState.Top;
addressForm.Left = AppState.FormState.Left;
//set the address list height
addressForm.AddressListPanel.Height = AppState.FormState.AddressListHeight;
//set the addresses
addresses = AppState.Addresses;
}
SaveState() accepts an AddressForm instance and a list of addresses. It then creates an instance ApplicationState an initializes it with a new FormState instance and with my list of addresses. Next ApplicationState is serialized to a binary file. ResumeState() accepts an AddressForm instance and a collection of Address objects. It's ref because we want to return the instance once it is deserialized rather than passing an actual reference. Next ApplicationState is deserialized from the previously created binary file. After deserialization, the AddressFrom properties are set, and the Address collection is pulled out to be returned via the ref parameter.
This is a very simple example, but it illustrates what is possbile.The beauty of using .NET serialization is that it will handle all the plumbing for you. As long as you can create the necessary Serializable classes, it will do the rest.
Sharp24597
There were DOS function available to assist with this, IIRC, so if you look up how those worked, you might be able to get them working or find a windows way of doing it.
Alternativly, there are some windows based text editors which can read chucks of the memory, and edit them. so maybe try looking up the sources for them.
Also, if you can look up how windows references programs and memory these days, then find the source to something the old dos debug tool
Dr.9
fighter92
For web apps, UIP application block comes quite close.
Pranshu