Set up a Windows C# application deployment - use of save state

108 views
Skip to first unread message

M Vallée

unread,
Jun 7, 2016, 10:33:40 AM6/7/16
to SWI-Prolog
Hi everyone,

I have developped a Windows C# addin (.dll file) that uses SWI Prolog and the CLP(FD) library, with Visual Studio 2013. It uses SwiPlCs.dll v1.1.60605.0 (64 bits) - I didn't forget to rename "SwiPlCs_64.dll" as "SwiPlCs.dll". 

For development, I set my PATH variable to the bin directory of my SWI Prolog package installation and wrote in my code :


if (!PlEngine.IsInitialized)

                {

                    PlEngine.Initialize(new string[] { "" });

                }



That worked fine.


Now, for deployment, I don't want the user to install the whole SWI-Prolog package. I want to copy what is needed at the right places and that everything remains transparent for the user.


As Jan Wielemaker told me, I successfully created a save state using qsave_program/2 :


qsave_program("save_state_stand_alone", [stand_alone(true),autoload(true),map(qsave)]).


Then, I called in my C# program :


if(!PlEngine.IsInitialized)

{

PlEngine.Initialize(newstring[] { "libswipl.dll", "-x", "save_state_stand_alone.exe"});

}


I also copied all the DLL contained in the "bin" directory next to my compiled release DLL. 


I get the following error message : "The specified module could not be found. (Exception from HRESULT: 0x8007007E)"


Is it the right thing to do? Can someone help me understand what I have to do?


Thanks a lot for your help.


Best regards

Jan Wielemaker

unread,
Jun 7, 2016, 11:08:04 AM6/7/16
to M Vallée, SWI-Prolog
On 07/06/16 16:33, M Vallée wrote:
> I get the following error message : "The specified module could
> not be found. (Exception from HRESULT: 0x8007007E)"
>

It is Windows very clear message to say it can't find a DLL or a DLL on
which the first DLL depends. Search for "Dependency walker" on
the internet and try one. Note that all DLLs should be in the same
directory as the original .exe or should be in %PATH%. In more recent
versions of Windows you can further adjust the search path using
the Windows AddDllDirectory() call. This all has more to do with
Windows than with Prolog though.

Cheers --- Jan

M Vallée

unread,
Jun 7, 2016, 11:53:37 AM6/7/16
to SWI-Prolog
I copied the whole bin directory next to my compiled DLL, changed the PATH directory to use this one, and now the Release DLL works when doing :
                    PlEngine.Initialize(new string[] { "libswipl.dll" });

Are these DLL enough for deployment ? Do I need to use a save state when initializing ?
If I copy the save_state next to my compiled DLL and write this
                     PlEngine.Initialize(new string[] { "libswipl.dll", "-x", "save_state.exe" });

my program keeps waiting, with no error, but nothing happens.
Message has been deleted

M Vallée

unread,
Jun 8, 2016, 5:48:03 AM6/8/16
to SWI-Prolog
I don't see if I need to create a .exe or a .prc file for the save state.
And how to call it with the SwiPlCs function PlEngine.Initialize.
Is it 
 PlEngine.Initialize(new string[] { "libswipl.dll", "-x", "save_state.exe" });
 PlEngine.Initialize(new string[] { "-x", "save_state.exe" });
 PlEngine.Initialize(new string[] { "libswipl.dll", "-x", "save_state" });

Can someone confirm to me the save state has to be next to libswipl.dll ?

Thanks

Jan Wielemaker

unread,
Jun 8, 2016, 5:59:33 AM6/8/16
to M Vallée, SWI-Prolog
On 06/08/2016 11:48 AM, M Vallée wrote:
> I don't see if I need to create a .exe or a .prc file for the save state.

The name of the file (including extension) doesn't matter.

> And how to call it with the SwiPlCs function PlEngine.Initialize.
> Is it
> PlEngine.Initialize(new string[] { "libswipl.dll", "-x",
> "save_state.exe" });

This is fine if you called the state "save_state.exe". As you don't
want to execute the state immediately, using .prc or any extension you
consider convenient might be a better choice.

> PlEngine.Initialize(new string[] { "-x", "save_state.exe" });

This is not. The first argument is either the running executable or
"libswipl.dll".

> PlEngine.Initialize(new string[] { "libswipl.dll", "-x", "save_state" });

As the file "save_state" doesn't exist I'd assume you get an error that
Prolog cannot find its resource database.

If it hangs, attach a debugger or add print statements to find out
where. Does it use resources (e.g., CPU) while hanging?

Cheers --- Jan
> --
> You received this message because you are subscribed to the Google
> Groups "SWI-Prolog" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to swi-prolog+...@googlegroups.com
> <mailto:swi-prolog+...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/swi-prolog.
> For more options, visit https://groups.google.com/d/optout.

Julio Di Egidio

unread,
Jun 8, 2016, 7:15:14 AM6/8/16
to SWI-Prolog

On Wednesday, June 8, 2016 at 11:48:03 AM UTC+2, M Vallée wrote:


> Can someone confirm to me the save state has to be next to libswipl.dll ?

Next to your executable program, not next to the libraries.  As Jan was saying,
"all DLLs should be **in the same directory as the original .exe** or should be
in %PATH% [or, anyway, in the searchable path]", my emphasis.

Julio

M Vallée

unread,
Jun 8, 2016, 9:01:15 AM6/8/16
to SWI-Prolog
Ok so I think I am starting to understand what happened.

The context :
I use SmartAssembly as an obfuscator for my DLL.
The compiled DLL is put into the "obj" directory of my VS solution, then SmartAssembly creates an obfuscated version of the DLL into the "bin" directory.

If I execute the not-obfuscated DLL, from the "obj" directory, with "mystate.exe" next to it, with this piece of code :
PlEngine.Initialize(new string[] { "libswipl.dll", "-x", "mystate.exe" });

it works fine.

If I execute the obfuscated DLL, from the "bin" directory, with "mystate.exe" next to it, the program hangs at initialization with no use of CPU/RAM...

I tried to attach the state to the not-obfuscated DLL before obfuscation, doing what is described here :

To create an executable that does not rely on Prolog one must create a saved state of the required Prolog code and attach this to the executable. Creating saved states is described with qsave_program/2 in the reference manual. This can be attached to a state using the DOS command below to create final.exe from the executable produced by MSVC and the generated saved state.
> copy /b file.exe+file.state final.exe

But it didn't work...

Any idea ?

M Vallée

unread,
Jun 8, 2016, 11:02:49 AM6/8/16
to SWI-Prolog
What is even stranger is that the not-obfuscating DLL works when the main program is executed from VS in release mode (with CTRL+F5, i.e. "Execute without debugging"). BUT it is not working when directly executed from the main program...

M Vallée

unread,
Jun 9, 2016, 5:26:13 AM6/9/16
to SWI-Prolog
I finally managed to do what I want.

For those interested I put that here : the save state file was not found when given with a relative path (and put next to the executed DLL) ; it worked when given with an absolute path.

I think it is because the main executing program is not my DLL and is located in another directory, where the prolog engine expected to find the file.

Thanks for those who tried to help me.

Jan Wielemaker

unread,
Jun 9, 2016, 5:44:30 AM6/9/16
to M Vallée, SWI-Prolog
On 09/06/16 11:26, M Vallée wrote:
> I finally managed to do what I want.

Great!

> For those interested I put that here : the save state file was not found
> when given with a relative path (and put next to the executed DLL) ; it
> worked when given with an absolute path.

The argument to -x is simply a file name. No search is performed to
find it, no extensions are tried, etc. You can take care of that any
way you want in the code that initializes Prolog.

> I think it is because the main executing program is not my DLL and is
> located in another directory, where the prolog engine expected to find
> the file.

Finding a state goes through a search process:

- If "-x file" is given, use that file
- Try to find the executable and see whether the state is added at
the end of the executable
- Try to find the Prolog home directory and see whether the state
is there
- give up

The way in which the second and third steps are done depends on the OS.

Cheers --- Jan


>
> Thanks for those who tried to help me.
>
>
>
> Le mercredi 8 juin 2016 17:02:49 UTC+2, M Vallée a écrit :
>
> What is even stranger is that the not-obfuscating DLL works when the
> main program is executed from VS in release mode (with CTRL+F5, i.e.
> "Execute without debugging"). BUT it is not working when directly
> executed from the main program...
>
Reply all
Reply to author
Forward
0 new messages