P4api.net & maxscript

Hi,

I’ve recently begun converting our internal perforce maxscript library from the now defunct p4dn.dll across to the new shiny p4api.net.dll available from perforce here;
http://www.perforce.com/product/components/tools-apis

However I’ve quickly run into problems creating a connection to the server and was wondering if anyone had encountered and resolved similar issues. Example code below;

(
	
	local sFilePath = (@"D:\p4api.net64\lib\") -- path to the perforce dll
	local p4DotNet = dotnet.loadAssembly ( sFilePath +"p4api.net.dll" )
	
	-- create the server address object. 
	local ServerAddress = dotNetObject "Perforce.P4.ServerAddress" @"leia:1666" -- using leia, our internal perforce server
	
	-- create a server object using ServerAddress.
	local Server = dotNetObject "Perforce.P4.Server" ServerAddress
	
	-- connect to the repository using Server
	local Repository = dotNetObject "Perforce.P4.Repository" Server
	
	-- attempt to access the Repository's connection
	local Con = try (Repository.connection) catch(format "%
" ( getCurrentException() ); undefined)
		-- alternativly attempt to directly create a connection using Server
	local Connection= try ( dotNetObject "Perforce.P4.Connection" Server) catch(format "%
" ( getCurrentException() ); undefined)
	
)

any help appreciated.

Cheers,

So it’s 18 months later, give or take, and I’ve come back to look at this. However the box fresh dlls from the Perforce website continue to exhibit the same behaviour. Has anyone found a work around to this?

All help appreciated.

Cheers,

What problem/error are you seeing exactly?

Do you have P4USER and P4PASSWD set as default on that machine? You need a user set to make a connection to Perforce and I don’t see one listed in the code.

Hi Adam,

Thanks for the response.

P4User and P4passwd are not required - at this point I’m simply setting up a connection to the repository. Once the repository is set up, by creating the serverAddress, and Server objects - I ought to be able to access the ‘connection’ property of repository, setup the user, password and client and finally call the Repository.connect() method to make a valid, usable connection. However, this is where the problems begin - when attempting to access Repository.connection the error;
‘Runtime error: dotNet runtime exception: Object reference not set to an instance of an object’
is thrown. It’s as if the Repository object is not being initialised correctly. Running the same code path in c#, using the same p4 library, works without problem. So the problem appears to be Max related(?), and not the dll - I’m wondering weather creating my own .net wrapper for the p4api.net.dll might be the way to go?

I have not tried to use this particular API with Perforce, so I don’t have any great ideas. Are you set on using the DLL? You might consider calling out to p4.exe via the command line instead.

I currently use the p4api.dll, basically a c# wrapper over the c++, which currently works pretty-much without issue. However Perforce don’t support this and as such it could stop working the next time we upgrade our version of P4D. So, trying to future proof against this potential problem, I thought I’d investigate moving our p4 maxscript library across to the supported .net api, which also appears a little more friendly, but it appears that Max is going to be a thorn in my side once again.

I’ll pop this back on the shelf for another 18 months then…

I’m actually re-writing ours as we speak.

I went the route of p4api.net, and writing a simplified wrapper in C# that maxscript can auto wrap as much as possible; Trying to keep the return values to basic types as much as i can, so maxscript does the auto conversion for me (c# arrays of string for example).

If you use the p4api.net you will need the p4bridge.dll in the same folder that you store your p4api.dll, or it will all fall apart.

I’m connecting with it as such (this is called via the maxscript wrapper.)

     
public static void Init(PerforceID id)
        {

            try
            {
                // initialize the connection variables
                // note: this is a connection without using a password

                // define the server, repository and connection
                Server server = new Server(new ServerAddress(id.ServerURI));
                Program._Repository_ = new Repository(server);

                Program._PerforceConnection_ = _Repository_.Connection;

                // use the connection varaibles for this connection
                Program._PerforceConnection_.UserName = id.UserName;
                Program._PerforceConnection_.Client = new Client();
                Program._PerforceConnection_.Client.Name = id.Workspace;

                // connect to the server
                Program._PerforceConnection_.Connect(null);

                Program._PerforceConnection_.Login(id.ClientPass);

                //Console.WriteLine("Perforce is Connected.");
                Kernel.Print("Successfully Connected to Perforce : [" + id.ServerURI + "] [" + id.UserName + "] [" + id.Workspace + "]");

            }
            catch (Exception ex)
            {
                // Add useful information to the exception
                // Console.WriteLine(ex.Message);
                Kernel.Print("Connection To Perforce Failed : 
	" + ex.Message);
            }

        }

I pulled this code off the net, and it is connecting as i’d want. You could probably grab the p4api dll’s and convert that to maxscript…

Hope that helps.

I’ve tried diving into the .Net API before and it’s pretty horrendous. From what I recall, the .NET API is a big fancy wrapper (with horrible documentation) around p4 command line calls… so why not just avoid that level of indirection entirely and wrap the command line calls in Maxscript? You could probably pull it off in a day or two instead of driving yourself crazy with a poor API that isn’t even really offering anything useful to you. In MaxScript, I’d recommend wrapping the DotNet Process class to call p4.exe (for general use and better control, including process communication, something that DOSCommand can’t give you).

Thanks for the advice.

@Andylt1, have you tried running the p4api.net.dll perforce connection directly through maxscript, rather than through a wrapper, could you get it to work? I have the bridge dll in the same folder, iirc without it the p4api dll won’t even initialise when loaded.

@Mouthlessbobcat, The current solution I have basically does what you suggest though is using the p4api.dll - this constructs command line arguments in a slightly nicer way than simply creating strings - its returns are also a little more helpful; errors, warnings, messages etc are all property arrays, so a simple (if p4return.errors.count > 0 do … ) is all that is needed to know that the operation has failed.