Advertisement
cgrunwald

Untitled

Feb 2nd, 2011
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.43 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using System.Runtime.InteropServices;
  4. using Microsoft.Build.Framework;
  5. using Microsoft.Build.Utilities;
  6.  
  7. namespace MsBuild.TiDesktop
  8. {
  9.     /// <summary>
  10.     ///
  11.     /// </summary>
  12.     public class BuildTask : Task
  13.     {
  14.         /// <summary>
  15.         /// To load the dll - <paramref name="dllFilePath"/> doesn't have to be
  16.         /// constant - so I can read path from registry
  17.         /// </summary>
  18.         /// <param name="dllFilePath">file path with file name</param>
  19.         /// <param name="hFile">use <see cref="IntPtr.Zero"/></param>
  20.         /// <param name="dwFlags">What will happened during loading dll
  21.         /// <para>LOAD_LIBRARY_AS_DATAFILE</para>
  22.         /// <para>DONT_RESOLVE_DLL_REFERENCES</para>
  23.         /// <para>LOAD_WITH_ALTERED_SEARCH_PATH</para>
  24.         /// <para>LOAD_IGNORE_CODE_AUTHZ_LEVEL</para>
  25.         /// </param>
  26.         /// <returns>Pointer to loaded Dll</returns>
  27.         [DllImport("KERNEL32.DLL")]
  28.         private static extern IntPtr LoadLibraryEx(string dllFilePath, IntPtr hFile, uint dwFlags);
  29.  
  30.         /// <summary>
  31.         /// To unload library
  32.         /// </summary>
  33.         /// <param name="dllPointer">Pointer to Dll witch was returned from <see cref="LoadLibraryEx"/></param>
  34.         /// <returns>If unloaded library was correct then <see langword="true"/>, else <see langword="false"/></returns>
  35.         [DllImport("KERNEL32.DLL")]
  36.         public static extern bool FreeLibrary(IntPtr dllPointer);
  37.  
  38.         /// <summary>
  39.         /// To get function pointer from loaded dll
  40.         /// </summary>
  41.         /// <param name="dllPointer">Pointer to Dll witch was returned from <see cref="LoadLibraryEx"/></param>
  42.         /// <param name="functionName">Function name with you want to call</param>
  43.         /// <returns>Pointer to function</returns>
  44.         [DllImport("KERNEL32.DLL")]
  45.         public static extern IntPtr GetProcAddress(IntPtr dllPointer, string functionName);
  46.  
  47.         /// <summary>
  48.         /// This will to load concrete dll file
  49.         /// </summary>
  50.         /// <param name="dllFilePath">Dll file path</param>
  51.         /// <returns>Pointer to loaded dll</returns>
  52.         /// <exception cref="ApplicationException">
  53.         /// when loading dll will failure
  54.         /// </exception>
  55.         public static IntPtr LoadWin32Library(string dllFilePath)
  56.         {
  57.             IntPtr moduleHandle = LoadLibraryEx(dllFilePath, IntPtr.Zero, 0x00000008);
  58.             if (moduleHandle == IntPtr.Zero) {
  59.                 // I'm gettin last dll error
  60.                 int errorCode = Marshal.GetLastWin32Error();
  61.                 throw new ApplicationException(
  62.                     string.Format("There was an error during dll loading : {0}, error - {1}", dllFilePath, errorCode)
  63.                     );
  64.             }
  65.             return moduleHandle;
  66.         }
  67.  
  68.         // **************************************************************************************************************************
  69.         // That is all, now how to use this functions
  70.         // **************************************************************************************************************************
  71.  
  72.         /// <summary>
  73.         ///
  74.         /// </summary>
  75.         /// <exception cref="ApplicationException"></exception>
  76.         public static void InitializeMyDll(string pathDLL, out IntPtr myDll)
  77.         {
  78.             try {
  79.                 myDll = LoadWin32Library(pathDLL);
  80.             }
  81.             catch (ApplicationException) {
  82.                 myDll = IntPtr.Zero;
  83.                 throw;
  84.             }
  85.         }
  86.  
  87.         // The last thing is to create delegate to calling function
  88.  
  89.         // delegate must to have the same parameter then calling function (from dll)
  90.         /// <summary>
  91.         ///
  92.         /// </summary>
  93.         /// <param name="argc"></param>
  94.         /// <param name="argv"></param>
  95.         [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
  96.         public delegate int Py_Main(int argc, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeConst = 9)] string[] argv);
  97.  
  98.         /// <summary>
  99.         ///
  100.         /// </summary>
  101.         /// <param name="pyPath"></param>
  102.         /// <param name="argc"></param>
  103.         /// <param name="argv"></param>
  104.         /// <returns></returns>
  105.         public static int PyMain(string pyPath, int argc, string[] argv)
  106.         {
  107.             IntPtr myDll;
  108.             InitializeMyDll(pyPath, out myDll);
  109.             if(myDll == IntPtr.Zero) {
  110.                 return 3;
  111.             }
  112.  
  113.             IntPtr pProc = GetProcAddress(myDll, @"Py_Main");
  114.             Delegate dPyMain = null;
  115.  
  116.  
  117.             try {
  118.                 dPyMain = Marshal.GetDelegateForFunctionPointer(pProc, typeof(Py_Main));
  119.             } catch (ArgumentException e) {
  120.                 Console.WriteLine(e.ParamName);
  121.                 Console.WriteLine(e.Message);
  122.                 Console.WriteLine(e);
  123.             }
  124.             if (dPyMain != null) {
  125.                 int _result = (int)(dPyMain.DynamicInvoke(argc, argv));
  126.                 FreeLibrary(myDll);
  127.                 return _result;
  128.             }
  129.            
  130.             return 3;
  131.         }
  132.        
  133.         // Now if you want to call dll function from program code use this
  134.         // for ex. you want to call c++ function RETURN_TYPE CallingFunctionNameFromCallingDllFile(int nID, LPSTR lpstrName);
  135.  
  136.         /// <summary>
  137.         /// Executes a task.
  138.         /// </summary>
  139.         /// <returns>
  140.         /// <see langword="true"/> if the task executed successfully; otherwise, <see langword="false"/>.
  141.         /// </returns>
  142.         public override bool Execute()
  143.         {
  144.             const string sdkVersion = "1.1.0";
  145.  
  146.             Log.LogMessage(MessageImportance.High, "Locating path to Titanium SDK.");
  147.             string pathProgData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); // Environment.GetEnvironmentVariable(@"ProgramData");
  148.             if(string.IsNullOrEmpty(pathProgData)) {
  149.                 Log.LogErrorFromException(new DirectoryNotFoundException("ProgramData couldn't be resolved."));
  150.                 return false;
  151.             }
  152.  
  153.             Log.LogMessage(MessageImportance.Low, String.Format("Checking if Titanium folder exists in {0}..", pathProgData));
  154.             pathProgData = Path.Combine(pathProgData, "Titanium");
  155.             if ((!Directory.Exists(pathProgData)) || (Directory.GetFileSystemEntries(pathProgData).Length < 1)) {
  156.                 Log.LogErrorFromException(new DirectoryNotFoundException("Directory \"" + pathProgData + "\" does not exist."));
  157.                 return false;
  158.             }
  159.            
  160.             // Resolve the paths.
  161.             Log.LogMessage(MessageImportance.Normal, "Verifying existence of Titanium's python distribution and build script.");
  162.             string pathPython = String.Format("{0}{1}modules{1}win32{1}python{1}{2}", pathProgData, Path.DirectorySeparatorChar, sdkVersion);
  163.             string pathBuildSDK = String.Format("{0}{1}sdk{1}win32{1}{2}", pathProgData, Path.DirectorySeparatorChar, sdkVersion);
  164.             string pathBuildScript = String.Format("{0}{1}tibuild.py", pathBuildSDK, Path.DirectorySeparatorChar);
  165.             string pathPyDll = Path.Combine(pathPython, "python25.dll");
  166.             string pathPyLib = String.Format("{0}{1}{0}{2}Lib{1}{0}{2}tcl{1}{0}{2}DLLs", pathPython, Path.PathSeparator, Path.DirectorySeparatorChar);
  167.             string pathPyBin = String.Format("{0}{1}{0}{2}Lib{2}Tools{2}Scripts", pathPython, Path.PathSeparator, Path.DirectorySeparatorChar);
  168.             if(!File.Exists(pathBuildScript)||!File.Exists(pathPyDll)) {
  169.                 Log.LogErrorFromException(new FileNotFoundException("Could not find tibuild.py. (or could not find interpreter to run it)"));
  170.                 Log.LogMessage(MessageImportance.High, "Verify they exist as \n{0}\nand\n{1}", pathPyDll, pathBuildScript);
  171.                 return false;
  172.             }
  173.             Environment.SetEnvironmentVariable("PATH", pathPyBin, EnvironmentVariableTarget.Process);
  174.             Environment.SetEnvironmentVariable("PYTHONPATH", pathPyLib, EnvironmentVariableTarget.Process);
  175.             Environment.SetEnvironmentVariable("PYTHONDEBUG", "1", EnvironmentVariableTarget.Process);
  176.  
  177.             // Temporary
  178.             string dest = Destination.ItemSpec;
  179.             string src = Source.ItemSpec;
  180.             String[] args = {
  181.                                 "python",
  182.                                 pathBuildScript,
  183.                                 "-d", dest,
  184.                                 "-s", String.Format("{0}{1}", pathProgData, Path.DirectorySeparatorChar),
  185.                                 "-a", pathBuildSDK,
  186.                                 src
  187.                             };
  188.  
  189.             if (PyMain(pathPyDll, 9, args) != 0) {
  190.                 _results = "Your Titanium build has failed.";
  191.                 Log.LogMessage(MessageImportance.High, _results);
  192.                 return false;
  193.             }
  194.             _results = "Your Titanium build has succeeded!";
  195.             return true;
  196.         }
  197.  
  198.         /// <summary>
  199.         ///
  200.         /// </summary>
  201.         [Required]
  202.         public ITaskItem Source
  203.         {
  204.             get { return _sourceFolder; }
  205.             set { _sourceFolder = value ?? _sourceFolder; }
  206.         }
  207.  
  208.         /// <summary>
  209.         ///
  210.         /// </summary>
  211.         [Required]
  212.         public ITaskItem Destination
  213.         {
  214.             get { return _destFolder; }
  215.             set { _destFolder = value ?? _destFolder; }
  216.         }
  217.  
  218.         /// <summary>
  219.         ///
  220.         /// </summary>
  221.         [Output]
  222.         public string Results
  223.         {
  224.             get { return !string.IsNullOrEmpty(_results) ? _results : "Failed"; }
  225.         }
  226.  
  227.         private string _results;
  228.         private ITaskItem _sourceFolder;
  229.         private ITaskItem _destFolder;
  230.  
  231.         /// <summary>
  232.         ///
  233.         /// </summary>
  234.         public BuildTask()
  235.         {
  236.             _results = String.Empty;
  237.         }
  238.     }
  239.  
  240.  
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement