<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>digital matter &#187; DLL</title>
	<atom:link href="http://blog.loadlimits.info/tag/dll/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.loadlimits.info</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Mon, 06 Feb 2012 13:27:58 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>NSISから使える、起動中のプロセスを削除するプラグイン</title>
		<link>http://blog.loadlimits.info/2009/09/nsis%e3%81%8b%e3%82%89%e4%bd%bf%e3%81%88%e3%82%8b%e3%80%81%e8%b5%b7%e5%8b%95%e4%b8%ad%e3%81%ae%e3%83%97%e3%83%ad%e3%82%bb%e3%82%b9%e3%82%92%e5%89%8a%e9%99%a4%e3%81%99%e3%82%8b%e3%83%97%e3%83%a9/</link>
		<comments>http://blog.loadlimits.info/2009/09/nsis%e3%81%8b%e3%82%89%e4%bd%bf%e3%81%88%e3%82%8b%e3%80%81%e8%b5%b7%e5%8b%95%e4%b8%ad%e3%81%ae%e3%83%97%e3%83%ad%e3%82%bb%e3%82%b9%e3%82%92%e5%89%8a%e9%99%a4%e3%81%99%e3%82%8b%e3%83%97%e3%83%a9/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 07:20:22 +0000</pubDate>
		<dc:creator>hotpi</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[解決]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[NSIS]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.loadlimits.info/2009/09/nsis%e3%81%8b%e3%82%89%e4%bd%bf%e3%81%88%e3%82%8b%e3%80%81%e8%b5%b7%e5%8b%95%e4%b8%ad%e3%81%ae%e3%83%97%e3%83%ad%e3%82%bb%e3%82%b9%e3%82%92%e5%89%8a%e9%99%a4%e3%81%99%e3%82%8b%e3%83%97%e3%83%a9/</guid>
		<description><![CDATA[常駐アプリケーションを作ったはいいが、アンインストールしようとしたときにプロセスが起動していると、削除できなくて困る。 というわけで、プロセスを殺す目的のプラグインDLLを作成。コンパイル済みファイルはエントリの最後に。 taskkillコマンド使えという話ですが、Windows XP Home Editionにはtaskkillコマンドが含まれていないので。 今回もさっくりC#で。C#.NETで作ってしまうと、そのままではNSISで使えないのだけど、.NETで作ったDLLをNSISのプラグインとして使う方法は以下のエントリを参照。 NSISで、C#で書かれた自作のDLLを使う : blog.loadlimit &#8211; digital matter - ソースは以下。C#でクラスライブラリとしてプロジェクトを作成。プロセス名を指定すると、マッチしたプロセスを全部終了してくれます。 using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace TaskKill { public class TaskKill { [DllImport("Psapi.dll", SetLastError = true)] static extern bool EnumProcesses( [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] [In][Out] UInt32[] processIds, UInt32 arraySizeBytes, [MarshalAs(UnmanagedType.U4)] out UInt32 bytesCopied ); [DllImport("kernel32.dll")] static extern [...]]]></description>
			<content:encoded><![CDATA[<p>常駐アプリケーションを作ったはいいが、アンインストールしようとしたときにプロセスが起動していると、削除できなくて困る。</p>
<p>というわけで、プロセスを殺す目的のプラグインDLLを作成。コンパイル済みファイルはエントリの最後に。</p>
<p>taskkillコマンド使えという話ですが、Windows XP Home Editionにはtaskkillコマンドが含まれていないので。</p>
<p>今回もさっくりC#で。C#.NETで作ってしまうと、そのままではNSISで使えないのだけど、.NETで作ったDLLをNSISのプラグインとして使う方法は以下のエントリを参照。</p>
<p><a title="http://blog.loadlimits.info/2009/08/nsis%e3%81%a7%e3%80%81c%e3%81%a7%e6%9b%b8%e3%81%8b%e3%82%8c%e3%81%9f%e8%87%aa%e4%bd%9c%e3%81%aedll%e3%82%92%e4%bd%bf%e3%81%86/" href="http://blog.loadlimits.info/2009/08/nsis%e3%81%a7%e3%80%81c%e3%81%a7%e6%9b%b8%e3%81%8b%e3%82%8c%e3%81%9f%e8%87%aa%e4%bd%9c%e3%81%aedll%e3%82%92%e4%bd%bf%e3%81%86/">NSISで、C#で書かれた自作のDLLを使う : blog.loadlimit &#8211; digital matter -</a></p>
<p>ソースは以下。C#でクラスライブラリとしてプロジェクトを作成。プロセス名を指定すると、マッチしたプロセスを全部終了してくれます。</p>
<p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:53c99b17-b530-4e95-997c-35715953896a" class="wlWriterEditableSmartContent">
<pre name="code" class="c#">using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace TaskKill
{
    public class TaskKill
    {
        [DllImport("Psapi.dll", SetLastError = true)]
        static extern bool EnumProcesses(
           [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] [In][Out] UInt32[] processIds,
             UInt32 arraySizeBytes,
             [MarshalAs(UnmanagedType.U4)] out UInt32 bytesCopied
          );

        [DllImport("kernel32.dll")]
        static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
           uint dwProcessId);

        [Flags]
        public enum ProcessAccessFlags : uint
        {
            All = 0x001F0FFF,
            Terminate = 0x00000001,
            CreateThread = 0x00000002,
            VMOperation = 0x00000008,
            VMRead = 0x00000010,
            VMWrite = 0x00000020,
            DupHandle = 0x00000040,
            SetInformation = 0x00000200,
            QueryInformation = 0x00000400,
            Synchronize = 0x00100000
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        [StructLayout(LayoutKind.Sequential)]
        public struct StringBuffer
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string text;
        }

        [DllImport("psapi.dll")]
        private static extern bool EnumProcessModules(IntPtr hProcess, out IntPtr lphModule, int cb, out int lpcbNeeded);
        [DllImport("psapi.dll")]
        private static extern int GetModuleBaseName(IntPtr hProcess, IntPtr hModule, out StringBuffer lpBaseName, int nSize);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool TerminateProcess(IntPtr hProcess, int uExitCode);

        public static void KillByName(string pname)
        {

            UInt32 arraySize = 1024;
            UInt32 arrayBytesSize = arraySize * sizeof(UInt32);
            UInt32[] processIds = new UInt32[arraySize];
            UInt32 bytesCopied;

            bool success = EnumProcesses(processIds, arrayBytesSize, out bytesCopied);

            if (!success)
            {
                return;
            }
            if (0 == bytesCopied)
            {
                return;
            }

            UInt32 numIdsCopied = bytesCopied &gt;&gt; 2;

            if (0 != (bytesCopied &amp; 3))
            {
                UInt32 partialDwordBytes = bytesCopied &amp; 3;

                return;
            }

            for (UInt32 index = 0; index &lt; numIdsCopied; index++)
            {
                IntPtr hProcess = OpenProcess(
                    ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VMRead | ProcessAccessFlags.Terminate,
                    false,processIds[index]);
                if (hProcess.ToInt32() != 0)
                {
                    IntPtr hMod = IntPtr.Zero;
                    int cbNeeded;
                    StringBuffer szProcessName;
                    szProcessName.text = "&lt;unknown&gt;";

                    if (EnumProcessModules(hProcess, out hMod, Marshal.SizeOf(hMod), out cbNeeded))
                    {
                        GetModuleBaseName(hProcess, hMod, out szProcessName, Marshal.SizeOf(szProcessName));
                    }

                    if (szProcessName.text == pname)
                    {
                        TerminateProcess(hProcess, -1);
                    }

                    CloseHandle(hProcess);
                }
            }

        }

    }
}
</pre>
</div>
<p>で、これをNSISの配布ファイルに含めておいて、</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e9619311-129a-4b77-9c2d-7fd6d50d64c6" class="wlWriterEditableSmartContent">
<pre name="code" class="py">; アンインストーラ
Section "Uninstall"
  ; アンインストールで使用するプラグインの準備
  InitPluginsDir
  SetOutPath $PLUGINSDIR
  File "TaskKill.dll"

  ; hogehoge.exeが起動していたら、それを落とす
  CLR::Call /NOUNLOAD "TaskKill.dll" "TaskKill.TaskKill" "KillByName" 1 "hogehoge.exe"

  ; インストールしたファイル群削除
  Delete $INSTDIR\*.*

  CLR::Destroy
SectionEnd
</pre>
</div>
<p>という感じでnsiファイルを記述。</p>
<p>ファイルは下記リンクからダウンロードしてお使いください。</p>
<p><a href="http://blog.loadlimits.info/wp-content/uploads/2009/09/TaskKill.dll" target="_blank">download TaskKill.dll</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.loadlimits.info/2009/09/nsis%e3%81%8b%e3%82%89%e4%bd%bf%e3%81%88%e3%82%8b%e3%80%81%e8%b5%b7%e5%8b%95%e4%b8%ad%e3%81%ae%e3%83%97%e3%83%ad%e3%82%bb%e3%82%b9%e3%82%92%e5%89%8a%e9%99%a4%e3%81%99%e3%82%8b%e3%83%97%e3%83%a9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

